获取字符串中两个字符串之间的字符串

我有一个字符串,比如:

"super example of string key : text I want to keep - end of my string"

我只想保留 "key : "" - "之间的字符串。我该怎么做?我必须使用正则表达式,还是可以用另一种方式?

359735 次浏览
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);

Regex 在这里有点过了。

可以使用 string.Split和超载,采取一个 string[]为分隔符,但这将 还有是过度杀伤。

看看 SubstringIndexOf-前者获取给定字符串的一部分,索引和长度,后者查找内部字符串/字符的索引。

也许,一个好的方法就是剪出一个 子串:

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);

没有正则表达式也可以做到

 input.Split(new string[] {"key :"},StringSplitOptions.None)[1]
.Split('-')[0]
.Trim();

您已经有了一些很好的答案,我意识到我提供的代码远远不是最有效和最干净的。然而,我认为它可能对教育目的有用。我们可以整天使用预构建的类和库。但是,如果不了解内在的运作机制,我们只是在模仿和重复,永远不会学到任何东西。这段代码可以工作,而且比其他一些代码更加基本或“原始”:

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;
}

您最终将所需的字符串分配给 parseString 变量。请记住,它还将捕获进行中的和前面的空格。请记住,字符串只是一个字符数组,可以像其他带有索引的数组一样进行操作。

保重。

根据您希望实现的健壮性/灵活性,这实际上可能有点棘手。下面是我使用的实现:

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 "
 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);

这就是我的方法

   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;
}

正如我常说的,没有什么是不可能的:

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.regarExpressions 的引用

希望我能帮上忙。

一个可行的 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

或者,使用正则表达式。

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;
}
}

由于 :-是独一无二的,你可以使用:

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];

你可以使用以下的扩展方法:

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 : ", " - ");

我觉得这个可行:

   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);
}
var matches = Regex.Matches(input, @"(?<=key :)(.+?)(?=-)");

这只返回“ key:”和下面出现的“-”之间的值

如果你正在寻找一行的解决方案,这就是它:

s.Substring(s.IndexOf("eT") + "eT".Length).Split("97".ToCharArray()).First()

使用 System.Linq的整个1行解决方案:

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());
}
}

我使用了 Vijay Singh Rana 的代码片段,基本上完成了工作。但是如果 firstString确实已经包含了 lastString,那么它就会引起问题。我想要的是从 JSON 响应(没有加载 JSON 解析器)中提取 access _ token。我的 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);
}

In C# 8.0 and above, you can use the range operator .. as in

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

详情请参阅 文件

可能是这样的

private static string Between(string text, string from, string to)
{
return text[(text.IndexOf(from)+from.Length)..text.IndexOf(to, text.IndexOf(from))];
}

如果你想处理子字符串对的 多次发生,没有正则表达式是不容易的:

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;

至少它避免了大多数异常,如果没有/单个子字符串匹配,则返回原始字符串。

当问题用一个单一的例子来陈述时,不可避免地会出现歧义,这个问题也不例外。

对于问题中给出的示例,所需的字符串是明确的:

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 : 是前面的字符串,而 -是下面的字符串。)我假设 PPFF前后都有单词边界(因此 PPAFF8不匹配)。

我的假设,正如派对帽所反映的那样,如下:

  • 第一个子字符串 PP可以在一个(或多个) FF子字符串之前,如果存在,则忽略该子字符串;
  • 如果在遇到 FF之前,PP后面跟着一个或多个 PP,则下列 PP是前面的字符串和后面的字符串之间的子字符串的一部分;
  • 如果在遇到 PP之前,PP后面跟着一个或多个 FF,则认为 PP后面的第一个 FF是以下字符串。

请注意,这里的许多答案只处理表单的字符串

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(或者更一般地说,这个字符是构成下面字符串的字符串)。

当然,如果我上面列出的假设发生了变化,那么正则表达式必须进行修改(如果可能的话)。

1. 移动光标以获得详细说明。

getStringBetween(startStr, endStr, fullStr) {
string startIndex = fullStr.indexOf(startStr);
string endIndex= fullStr.indexOf(endStr);
return fullStr.substring(startIndex + startStr.length, endIndex);
}
  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);






}

就是这个

 /// <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>

如果有人对保留开始和结束文本感兴趣,下面是扩展方法。

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));
}
    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

对于字符串之间的字符串,我使用以下方法:

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);
}
}