답변:
정규식없이 할 수 있습니다.
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 "
InvariantCulture
Windows 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
하나 이상의 FF
s 가 뒤에 오는 경우 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