>我有以下字符串:
[The quick] brown fox [mykey*="is a super-fast9"] animal [mykey^="that"] can run "very rapid" and [otherkey="effortlessly"].
我需要在双引号中提取单词(用空格分隔(,同时在以特定关键字(mykey(开头的括号内。
到目前为止,我有:
快速
mykey*="is
一个
超快9">
mykey^="that">
其他键="毫不费力">
但我想要:
是
一个
超快9
那
示例链接:https://regex101.com/r/zmNse1/2
Wiktor提供的解决方案是最合乎逻辑的,但为了正则表达式挑战,请参阅此模式[(?!mykey)[^[]+|([^s[="]+)(?=[^"]*"])
,检查组#1
[ # "["
(?! # Negative Look-Ahead
mykey # "mykey"
) # End of Negative Look-Ahead
[^[] # Character not in [[] Character Class
+ # (one or more)(greedy)
| # OR
( # Capturing Group (1)
[^s[="] # Character not in [s[="] Character Class
+ # (one or more)(greedy)
) # End of Capturing Group (1)
(?= # Look-Ahead
[^"] # Character not in ["] Character Class
* # (zero or more)(greedy)
" # """
] # "]"
) # End of Look-Ahead
您可以使用相对简单的正则表达式匹配所需的子字符串,并捕获引号之间的部分,然后用一个或多个空格模式拆分捕获:
var pattern = "\[mykey[^][=]+="([^"]*)"]";
var s = "[The quick] brown fox [mykey*="is a super-fast9"] animal [mykey^="that"] can run "very rapid".";
var result = Regex.Matches(s, pattern)
.Cast<Match>()
.SelectMany(v => v.Groups[1].Value.Trim().Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries))
.ToList();
Console.WriteLine(string.Join("n", result));
请参阅 C# 演示。
模式是
[mykey[^][=]+="([^"]*)"]
请参阅正则表达式演示。
图案详细信息
[
- 字面[
mykey
- 文本子字符串[^][=]+
- 除[
、]
和=
以外的 1 个或多个字符=
- 等号"
- 双引号([^"]*)
- 第 1 组:除"
以外的任何 0+ 字符"]
- 文本"]
子字符串。
请注意,捕获的值首先从前导/尾随空格(使用.Trim()
(修剪,以避免结果中的空值。@"s+"
匹配 1 个或多个空格字符。.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries)
用空格拆分组 1 值。
这个正则表达式应该做你想做的:(?<=[mykey.?="[^]]*)[w-]+(?=[^]]*"])
演示在这里
我假设不能有嵌套括号。我也不知道如何处理mykey
和=
之间的^
或*
,所以我允许一个可选的通配符.
您可能需要转义代码中的反斜杠。
对于它的价值:由于其他人提到了字符串解析,我想我会在这里给出一个实现。 字符串解析选项总是冗长,但比正则表达式快几个数量级。 作为一个经常使用正则表达式的人,我仍然可以说我尽可能更喜欢字符串函数。 这个答案的唯一复杂之处在于你必须知道你的赋值运算符是什么,并且你不能在你的字符串值中使用转义的双引号。 我写得相当冗长,尽管如果你想要更少的代码字节,你可以删去一些条件或缩短一些行。
List<string> GetValuesByKeyword(string keyword, string input)
{
var vals = new List<string>();
int startIndex = input.IndexOf("[");
while (startIndex >= 0)
{
var newValue = "";
if (startIndex >= 0 && startIndex < input.Length - 1)
{
var squareKey = input.Substring(startIndex + 1).Trim();
if (squareKey.StartsWith(keyword))
{
var squareAssign = squareKey.Substring(keyword.Length).Trim();
var assignOp = StartsWithWhich(squareAssign, "=", "+=", "-=", "*=", "/=", "^=", "%=");
if (!string.IsNullOrWhiteSpace(assignOp))
{
var quotedVal = squareAssign.Substring(assignOp.Length).Trim();
if (quotedVal.StartsWith("""))
{
var endQuoteIndex = quotedVal.IndexOf('"', 1);
if (endQuoteIndex > 0)
{
newValue = quotedVal.Substring(1, endQuoteIndex - 1);
}
}
}
}
}
if (!string.IsNullOrWhiteSpace(newValue))
{
vals.Add(newValue);
startIndex = input.IndexOf("[", input.IndexOf(newValue, startIndex) + newValue.Length);
}
else startIndex = input.IndexOf("[", startIndex + 1);
}
return string.Join(" ", vals).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
}