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

时间:2017-08-08 13:15:56

标签: c# .net regex

我有以下字符串:

[The quick] brown fox [mykey*="is a super-fast9"] animal [mykey^="that"] can run "very rapid" and [otherkey="effortlessly"].

我需要在双引号内提取单词(用空格分隔),这些单词在括号内同时以特定关键字(mykey)开头。

到目前为止,我有:

快速

的myKey * ="是

超fast9"

的myKey ^ ="即"

otherkey ="毫不费力"

但我想:

超fast9

示例链接:https://regex101.com/r/zmNse1/2

4 个答案:

答案 0 :(得分:2)

Wiktor提供的解决方案是最合乎逻辑的,但为了RegEx挑战,请参阅此模式\[(?!mykey)[^\[]+|([^\s\[=\"]+)(?=[^\"]*\"\]),检查组#1 Demo

\[                  # "["
(?!                 # 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

答案 1 :(得分:1)

您可以使用相对简单的正则表达式匹配所需的子字符串,并在引号之间捕获部分,然后使用1个或多个空格模式拆分捕获:

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

请参阅the C# demo

模式是

\[mykey[^][=]+="([^"]*)"]

请参阅regex demo

模式详情

  • \[ - 文字[
  • mykey - 文字子字符串
  • [^][=]+ - 除[]=
  • 以外的1个或多个字符
  • = - 等号
  • " - 双引号
  • ([^"]*) - 第1组:除"
  • 以外的任何0 +字符
  • "] - 文字"]子字符串。

请注意,捕获的值首先从前导/尾随空格(使用.Trim())进行修剪,以避免结果中出现空值。 @"\s+"匹配1个或多个空格字符。 .Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries)用空格分割Group 1值。

答案 2 :(得分:1)

这个正则表达式应该做你想要的:
(?<=\[mykey.?="[^]]*)[\w-]+(?=[^]]*"\])

演示here

我假设不能有嵌套括号。另外,我不知道如何处理^*mykey之间的=,因此我允许使用可选的通配符。
您可能需要转义代码中的反斜杠。

答案 3 :(得分:0)

它的价值:由于其他人提到了String Parsing,我想我在这里给出了一个实现。字符串解析选项总是啰嗦,但比正则表达式快几个数量级。作为一个使用Regex的人,我仍然可以说我更喜欢字符串函数。这个答案的唯一复杂因素是您必须知道您的赋值运算符是什么,并且您不能在字符串值中包含Escaped Double-Quotes。我写得相当冗长,但如果你想要更少的代码字节,你可以删除一些条件或缩短一些行。

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