正则表达式 - 如果仅以关键字开头,则提取括号和引号内的单词



>我有以下字符串:

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

最新更新