답변:
정규식없이 할 수 있습니다.
input.Split(new string[] {"key :"},StringSplitOptions.None)[1]
.Split('-')[0]
.Trim();
구현이 얼마나 강력하고 유연한 지에 따라 실제로는 약간 까다로울 수 있습니다. 내가 사용하는 구현은 다음과 같습니다.
public static class StringExtensions {
/// <summary>
/// takes a substring between two anchor strings (or the end of the string if that anchor is null)
/// </summary>
/// <param name="this">a string</param>
/// <param name="from">an optional string to search after</param>
/// <param name="until">an optional string to search before</param>
/// <param name="comparison">an optional comparison for the search</param>
/// <returns>a substring based on the search</returns>
public static string Substring(this string @this, string from = null, string until = null, StringComparison comparison = StringComparison.InvariantCulture)
{
var fromLength = (from ?? string.Empty).Length;
var startIndex = !string.IsNullOrEmpty(from)
? @this.IndexOf(from, comparison) + fromLength
: 0;
if (startIndex < fromLength) { throw new ArgumentException("from: Failed to find an instance of the first anchor"); }
var endIndex = !string.IsNullOrEmpty(until)
? @this.IndexOf(until, startIndex, comparison)
: @this.Length;
if (endIndex < 0) { throw new ArgumentException("until: Failed to find an instance of the last anchor"); }
var subString = @this.Substring(startIndex, endIndex - startIndex);
return subString;
}
}
// usage:
var between = "a - to keep x more stuff".Substring(from: "-", until: "x");
// returns " to keep "
InvariantCultureWindows Universal Apps에서 작동하지 않습니다. 클래스의 기능을 유지하면서 제거 할 수있는 방법이 있습니까? @ChaseMedallion
나는 이것이 작동한다고 생각한다.
static void Main(string[] args)
{
String text = "One=1,Two=2,ThreeFour=34";
Console.WriteLine(betweenStrings(text, "One=", ",")); // 1
Console.WriteLine(betweenStrings(text, "Two=", ",")); // 2
Console.WriteLine(betweenStrings(text, "ThreeFour=", "")); // 34
Console.ReadKey();
}
public static String betweenStrings(String text, String start, String end)
{
int p1 = text.IndexOf(start) + start.Length;
int p2 = text.IndexOf(end, p1);
if (end == "") return (text.Substring(p1));
else return text.Substring(p1, p2 - p1);
}
여기서 정규식은 과잉입니다.
당신은 할 수 사용 string.Split걸리는 과부하 string[]구분 기호에 대한하지만 것 또한 과잉합니다.
봐 Substring와 IndexOf- 주어진 문자열과 인덱스와 길이 및 내부 문자열 / 문자의 색인을 찾기위한 두 번째의 일부를 얻을 전자를.
string.Split합니다.
작동하는 LINQ 솔루션 :
string str = "super exemple of string key : text I want to keep - end of my string";
string res = new string(str.SkipWhile(c => c != ':')
.Skip(1)
.TakeWhile(c => c != '-')
.ToArray()).Trim();
Console.WriteLine(res); // text I want to keep
이후 :와는 -고유 당신은 사용할 수 있습니다 :
string input;
string output;
input = "super example of string key : text I want to keep - end of my string";
output = input.Split(new char[] { ':', '-' })[1];
또는 정규식으로.
using System.Text.RegularExpressions;
...
var value =
Regex.Match(
"super exemple of string key : text I want to keep - end of my string",
"key : (.*) - ")
.Groups[1].Value;
실행 예제 와 함께 .
과잉인지 결정할 수 있습니다.
검증되지 않은 확장 방법으로
using System.Text.RegularExpressions;
public class Test
{
public static void Main()
{
var value =
"super exemple of string key : text I want to keep - end of my string"
.Between(
"key : ",
" - ");
Console.WriteLine(value);
}
}
public static class Ext
{
static string Between(this string source, string left, string right)
{
return Regex.Match(
source,
string.Format("{0}(.*){1}", left, right))
.Groups[1].Value;
}
}
아래 확장 방법을 사용할 수 있습니다.
public static string GetStringBetween(this string token, string first, string second)
{
if (!token.Contains(first)) return "";
var afterFirst = token.Split(new[] { first }, StringSplitOptions.None)[1];
if (!afterFirst.Contains(second)) return "";
var result = afterFirst.Split(new[] { second }, StringSplitOptions.None)[0];
return result;
}
사용법은 다음과 같습니다.
var token = "super exemple of string key : text I want to keep - end of my string";
var keyValue = token.GetStringBetween("key : ", " - ");
기본적으로 작업을 수행하는 Vijay Singh Rana의 코드 스 니펫을 사용했습니다. 그러나에 firstString이미 lastString. 내가 원했던 것은 JSON 응답에서 access_token을 추출하는 것입니다 (JSON 파서가로드되지 않음). 내가 firstString있었다 \"access_token\": \"나의이 lastString있었다 \". 나는 약간의 수정으로 끝났다
string Between(string str, string firstString, string lastString)
{
int pos1 = str.IndexOf(firstString) + firstString.Length;
int pos2 = str.Substring(pos1).IndexOf(lastString);
return str.Substring(pos1, pos2);
}
단선 솔루션을 찾고 있다면 다음과 같습니다.
s.Substring(s.IndexOf("eT") + "eT".Length).Split("97".ToCharArray()).First()
다음과 같은 전체 1 줄 솔루션 System.Linq:
using System;
using System.Linq;
class OneLiner
{
static void Main()
{
string s = "TextHereTisImortant973End"; //Between "eT" and "97"
Console.WriteLine(s.Substring(s.IndexOf("eT") + "eT".Length)
.Split("97".ToCharArray()).First());
}
}
당신은 이미 좋은 대답을 가지고 있으며 내가 제공하는 코드가 가장 효율적이고 깨끗한 것과는 거리가 멀다는 것을 알고 있습니다. 그러나 나는 그것이 교육적인 목적으로 유용 할 것이라고 생각했습니다. 사전 구축 된 클래스와 라이브러리를 하루 종일 사용할 수 있습니다. 그러나 내면의 작용을 이해하지 못하면 우리는 단순히 모방하고 반복하고 있으며 아무것도 배우지 않을 것입니다. 이 코드는 작동하며 다른 코드보다 더 기본적이거나 "처음"입니다.
char startDelimiter = ':';
char endDelimiter = '-';
Boolean collect = false;
string parsedString = "";
foreach (char c in originalString)
{
if (c == startDelimiter)
collect = true;
if (c == endDelimiter)
collect = false;
if (collect == true && c != startDelimiter)
parsedString += c;
}
parsedString 변수에 할당 된 원하는 문자열로 끝납니다. 진행 및 이전 공간도 캡처합니다. 문자열은 단순히 인덱스 등을 사용하여 다른 배열처럼 조작 할 수있는 문자 배열입니다.
조심해.
하위 문자열 쌍의 여러 항목 을 처리하려는 경우 RegEx 없이는 쉽지 않습니다.
Regex.Matches(input ?? String.Empty, "(?=key : )(.*)(?<= - )", RegexOptions.Singleline);
input ?? String.Empty인수 null 예외 방지?=첫 번째 부분 문자열을?<=유지하고 두 번째 부분 문자열을 유지합니다.RegexOptions.Singleline하위 문자열 쌍 사이에 줄 바꿈 허용
하위 문자열의 순서 및 발생 횟수가 중요하지 않은 경우이 빠르고 더러운 것이 옵션 일 수 있습니다.
var parts = input?.Split(new string[] { "key : ", " - " }, StringSplitOptions.None);
string result = parts?.Length >= 3 ? result[1] : input;
적어도 일치하는 부분 문자열이 하나도 없으면 원래 문자열을 반환하여 대부분의 예외를 피합니다.
항상 불가능한 것은 없습니다.
string value = "super exemple of string key : text I want to keep - end of my string";
Regex regex = new Regex(@"(key \: (.*?) _ )");
Match match = regex.Match(value);
if (match.Success)
{
Messagebox.Show(match.Value);
}
System.Text.RegularExpressions의 참조를 추가해야하는 기억
내가 도왔기를 바랍니다.
아마도 이런 것
private static string Between(string text, string from, string to)
{
return text[(text.IndexOf(from)+from.Length)..text.IndexOf(to, text.IndexOf(from))];
}
단일 예를 들어 질문이 언급 될 때 모호함이 필연적으로 존재합니다. 이 질문도 예외는 아닙니다.
질문에 주어진 예에서 원하는 문자열은 명확합니다.
super example of string key : text I want to keep - end of my string
^^^^^^^^^^^^^^^^^^^
그러나이 문자열은 특정 하위 문자열을 식별 할 문자열 및 경계 문자열의 예일뿐입니다. 다음과 같이 일반 경계 문자열이있는 일반 문자열을 고려합니다.
abc FF def PP ghi,PP jkl,FF mno PP pqr FF,stu FF vwx,PP yza
^^^^^^^^^^^^ ^^^^^
PP은 앞의 문자열 이고 FF다음 문자열이며 파티 모자는 일치 할 부분 문자열을 나타냅니다. (질문에 주어진 예에서 key : 앞의 문자열이고 -다음과 같은 문자열입니다.) 나는 가정 한 PP과 FF선행과 (그래서 단어 경계가옵니다 PPA과 FF8일치하지 않습니다).
파티 모자에 반영된 내 가정은 다음과 같습니다.
PP앞에는 하나 (또는 그 이상의) FF부분 문자열이 올 수 있으며, 존재하는 경우 무시됩니다.PP한 뒤에 이상 PP전에 s의 FF발생은 다음 PP들 이전 및 다음 문자열의 문자열의 일부이고;PP하나 이상의 FFs 가 뒤에 오는 경우 PP첫 번째 FF다음 PP은 다음 문자열로 간주됩니다.여기에있는 많은 답변은 다음 형식의 문자열 만 다룹니다.
abc PP def FF ghi
^^^^^
또는
abc PP def FF ghi PP jkl FF mno
^^^^^ ^^^^^
관심있는 부분 문자열을 식별하기 위해 정규식, 코드 구조 또는 두 가지 조합을 사용할 수 있습니다. 나는 어떤 접근법이 가장 좋은지 판단하지 않습니다. 관심있는 부분 문자열과 일치하는 다음 정규식 만 제시하겠습니다.
(?<=\bPP\b)(?:(?!\bFF\b).)*(?=\bFF\b)
엔진 시동! 1
나는 이것을 PCRE (PHP) 정규식 엔진으로 테스트했지만 정규식이 전혀 이국적이지 않기 때문에 .NET 정규식 엔진 (매우 강력 함)에서 작동 할 것이라고 확신합니다.
정규식 엔진은 다음 작업을 수행합니다.
(?<= : begin a positive lookbehind
\bPP\b : match 'PP'
) : end positive lookbehind
(?: : begin a non-capture group
(?! : begin a negative lookahead
\bFF\b : match 'FF'
) : end negative lookahead
. : match any character
) : end non-capture group
* : execute non-capture group 0+ times
(?= : begin positive lookahead
\bFF\b : match 'FF'
) : end positive lookahead
한 번에 하나의 문자를 일치시키고 앞의 문자열 다음에 문자 F가 뒤따를 때까지 F(또는보다 일반적으로 문자가 다음 문자열을 구성하는 문자열이 됨) Tempered Greedy Token Solution 이라고 합니다.
당연히 위에서 설명한 가정이 변경되면 정규식을 수정해야합니다 (가능한 경우).
1. 자세한 설명을 보려면 커서를 이동하십시오.
C # 8.0 이상에서는 다음과 같이 범위 연산자 ..를 사용할 수 있습니다.
var s = "header-THE_TARGET_STRING.7z";
var from = s.IndexOf("-") + "-".Length;
var to = s.IndexOf(".7z");
var versionString = s[from..to]; // THE_TARGET_STRING
자세한 내용은 설명서 를 참조하십시오.
substring하고indexof