我有一个像这样的字符串:
"super example of string key : text I want to keep - end of my string"
我只想保留 and 之间的"key : "
字符串" - "
。我怎样才能做到这一点?我必须使用正则表达式还是可以以其他方式进行?
也许,一个好方法就是剪掉一个子字符串:
String St = "super exemple of string key : text I want to keep - end of my string";
int pFrom = St.IndexOf("key : ") + "key : ".Length;
int pTo = St.LastIndexOf(" - ");
String result = St.Substring(pFrom, pTo - pFrom);
string input = "super exemple of string key : text I want to keep - end of my string";
var match = Regex.Match(input, @"key : (.+?)-").Groups[1].Value;
或仅使用字符串操作
var start = input.IndexOf("key : ") + 6;
var match2 = input.Substring(start, input.IndexOf("-") - start);
你可以在没有正则表达式的情况下做到这一点
input.Split(new string[] {"key :"},StringSplitOptions.None)[1]
.Split('-')[0]
.Trim();
这是我可以做到的方式
public string Between(string STR , string FirstString, string LastString)
{
string FinalString;
int Pos1 = STR.IndexOf(FirstString) + FirstString.Length;
int Pos2 = STR.IndexOf(LastString);
FinalString = STR.Substring(Pos1, Pos2 - Pos1);
return FinalString;
}
根据您希望实现的健壮/灵活程度,这实际上可能有点棘手。这是我使用的实现:
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 "
我认为这有效:
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);
}
一个有效的 LINQ 解决方案:
string str = "super example 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 str="super exemple of string key : text I want to keep - end of my string";
int startIndex = str.IndexOf("key") + "key".Length;
int endIndex = str.IndexOf("-");
string newString = str.Substring(startIndex, endIndex - startIndex);
由于 the:
和 the-
是独一无二的,您可以使用:
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;
}
}
在 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
有关详细信息,请参阅文档。
我使用了 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);
}
您可以使用以下扩展方法:
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 : ", " - ");
如果您正在寻找 1 行解决方案,就是这样:
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());
}
}
var matches = Regex.Matches(input, @"(?<=key :)(.+?)(?=-)");
这仅返回“key :”和以下出现的“-”之间的值
当用一个例子来陈述问题时,不可避免地会出现模棱两可的情况。这个问题也不例外。
对于问题中给出的示例,所需的字符串很清楚:
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
andFF
之前和之后是单词边界(所以PPA
andFF8
不匹配)。
正如党帽所反映的,我的假设如下:
PP
前面可以有一个(或多个)FF
子字符串,如果存在,则忽略这些子字符串;PP
后面遇到一个或多个PP
s before ,则后面的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)
我使用 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. 移动光标查看详细说明。
private string gettxtbettwen(string txt, string first, string last)
{
StringBuilder sb = new StringBuilder(txt);
int pos1 = txt.IndexOf(first) + first.Length;
int len = (txt.Length ) - pos1;
string reminder = txt.Substring(pos1, len);
int pos2 = reminder.IndexOf(last) - last.Length +1;
return reminder.Substring(0, pos2);
}
如果你想处理多次出现的子串对,没有 RegEx 就不容易了:
Regex.Matches(input ?? String.Empty, "(?=key : )(.*)(?<= - )", RegexOptions.Singleline);
input ?? String.Empty
避免参数空异常?=
保留第一个子串并?<=
保留第二个子串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 的引用
希望我有所帮助。
你已经有了一些很好的答案,我意识到我提供的代码远非最有效和最干净的。但是,我认为它可能对教育目的有用。我们可以整天使用预先构建的类和库。但如果不了解内部运作,我们只是在模仿和重复,永远不会学到任何东西。此代码有效,并且比其他一些代码更基本或“处女”:
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 变量。请记住,它还将捕获进行中和前面的空格。请记住,字符串只是一个字符数组,可以像其他具有索引等的数组一样进行操作。
小心。
public static string ExtractBetweenTwoStrings(string FullText, string StartString, string EndString, bool IncludeStartString, bool IncludeEndString)
{
try { int Pos1 = FullText.IndexOf(StartString) + StartString.Length; int Pos2 = FullText.IndexOf(EndString, Pos1); return ((IncludeStartString) ? StartString : "")
+ FullText.Substring(Pos1, Pos2 - Pos1) + ((IncludeEndString) ? EndString : ""); } catch (Exception ex) { return ex.ToString(); } //return ""; }
}
归功于:https ://www.c-sharpcorner.com/blogs/how-to-extract-a-string-lies-between-two-strings-in-c-sharpnet1
可能是这样的
private static string Between(string text, string from, string to)
{
return text[(text.IndexOf(from)+from.Length)..text.IndexOf(to, text.IndexOf(from))];
}
这是扩展方法,以防任何人也有兴趣保留开始和结束文本。
public static string SubstringBetween(this string text, string start, string end, bool keepStartEndText = false)
{
var startIndex = text.IndexOf(start);
var endIndex = text.LastIndexOf(end);
if (keepStartEndText)
return text.Substring(startIndex, (endIndex + end.Length) - startIndex);
else
return text.Substring(startIndex + start.Length, endIndex - (startIndex + start.Length));
}
getStringBetween(startStr, endStr, fullStr) {
string startIndex = fullStr.indexOf(startStr);
string endIndex= fullStr.indexOf(endStr);
return fullStr.substring(startIndex + startStr.length, endIndex);
}
对于字符串之间的获取字符串,我使用这种方法:
public static class Extension
{
/// <summary>
/// Gets currently string between
/// </summary>
/// <param name="word">Currently string</param>
/// <param name="start">String left</param>
/// <param name="end">String right</param>
/// <returns>String between start and end</returns>
/// <example>The string "value (4815162342)" use Between("(",")") generates in method: "4815162342"</example>
public static string Between(this string word, string start, string end)
{
if (start.Equals(end))
throw new ArgumentException("Start string can't equals a end string.");
int startIndex = word.LastIndexOf(start) + 1;
int endIndex = word.LastIndexOf(end) - 1 - word.LastIndexOf(start);
return word.Substring(startIndex, endIndex);
}
}
这里是;
/// <summary>
///
/// </summary>
/// <param name="line"></param>
/// <param name="begin_tag"></param>
/// <param name="end_tag"></param>
/// <param name="lastIndexOfEndTag"></param>
/// <returns></returns>
private string getBetween(string line, string begin_tag, string end_tag, bool lastIndexOfEndTag = false, bool returnNullIfTagsNotExists = false)
{
if (!string.IsNullOrEmpty(line) && !string.IsNullOrEmpty(begin_tag) && !string.IsNullOrEmpty(end_tag))
{
// 1 2 3 4 5 6 7
//0123456789012345678901234567890123456789012345678901234567890123456789012
//StdErrorData: Duration: 01:59:54.88, start: 0.000000, bitrate: 557 kb/s
int startIndex = line.IndexOf(begin_tag);
if (startIndex >= 0)
{
startIndex += begin_tag.Length;
}
else
{
if (returnNullIfTagsNotExists)
{
return null;
}
else
{
startIndex = 0;
}
}
int endIndex = lastIndexOfEndTag ?
line.LastIndexOf(end_tag, startIndex)
: line.IndexOf(end_tag, startIndex);
if (endIndex > startIndex)
{
return line.Substring(startIndex, endIndex - startIndex);
}
else
{
if (returnNullIfTagsNotExists)
{
return null;
}
else
{
return line.Substring(startIndex);
}
}
}
return null;
}
测试;
string r = getBetween("StdErrorData: Duration: 01:59:54.88, start: 0.000000, bitrate: 557 kb/s", "Duration:", ",");
Console.WriteLine($"<{r}>");
//< 01:59:54.88>