Answers:
也许,一个好方法就是切出一个子字符串:
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();
根据您希望实现的鲁棒性/灵活性,这实际上可能有些棘手。这是我使用的实现:
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
这是我可以做到的方式
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;
}
我认为这可行:
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[]
的分隔符,但会也矫枉过正。
string.Split
。
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);
或者,使用正则表达式。
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响应(未加载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);
}
如果您正在寻找一线解决方案,那就是:
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;
至少,如果没有/单个子字符串匹配,则通过返回原始字符串来避免大多数异常。
像这样的东西
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
s是子字符串的一部分。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)regex引擎对此进行了测试,但是由于regex一点都不陌生,因此我确信它可以与.NET regex引擎一起使用(功能非常强大)。
正则表达式引擎执行以下操作:
(?<= : 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.移动光标以获取详细说明。
substring
和indexof