【问题标题】:Get each item within a capturing group获取捕获组中的每个项目
【发布时间】:2017-08-08 00:24:03
【问题描述】:

如果你有这样的字符串:

[hello world] this is [the best .Home] is nice place.

如何仅在括号[] 中提取每个单词(以空格分隔)。 现在我有这个工作https://regex101.com/r/Tgokeq/2

返回

你好世界

最好的.Home

但我想要:

你好

世界

最好的

.首页

PS:我知道我可以在 foreach 中进行字符串拆分,但我不希望在正则表达式本身中使用它,就像这样可以获取每个单词,除了我只想要括号 [] 内的单词。 https://regex101.com/r/eweRWj/2

【问题讨论】:

  • 我已经知道我可以做到这一点,正如您在帖子的最后一段中看到的那样。

标签: c# .net regex


【解决方案1】:

使用这个模式([^\[\] ]+)(?=[^\[\]]*\])Demo

(               # Capturing Group (1)
  [^\[\] ]      # Character not in [\[\] ] 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

【讨论】:

  • 完美。正是我想要的,感谢您的解释。
  • 这在 python 中是不可能的,对吧?因为 python 认为你只有一个捕获组。
  • @TheChetan,我不知道python,但你也可以在不捕获组的情况下检查整个匹配
【解决方案2】:

这种模式可能看起来不那么优雅,因为它不单独匹配单个单词。完整的解决方案利用 .Net 正则表达式库来获取单个单词。但是,它避免了过度回溯 alpha bravo 的解决方案。其重要性在很大程度上取决于您搜索的行数和/或一次匹配大块文本还是仅匹配单个行。

这种方法还可以让您准确识别有多少括号对以及每对中捕获了哪些单词。一个简单的仅模式解决方案只会让您获得匹配的单词而无需上下文。

图案:

\[\s*((?<word>[^[\]\s]+)\s*)+]

然后是一些简短的代码,演示如何通过 .Net 正则表达式对象模型获取捕获的单词:

using System.Text.RegularExpressions;
...

Regex rx = new Regex(@"\[\s*((?<word>[^[\]\s]+)\s*)+]");
MatchCollection matches = rx.Matches(searchText);
foreach(Match m in matches) {
    foreach(Capture c in m.Groups["word"].Captures) {
        System.Console.WriteLine(c.Value);
    }
}

模式分解:

\[              # Opening bracket
  \s*           # Optional white space
  (             # Group for word delimited by space
    (?<word>    # Named capture group
      [^[\]\s]  # Negative character class: no brackets, no white space
      +         # one or more greedy
    )           # End named capture group
    \s*         # Match white space after word
  )             # End of word+space grouping
  +             # Match multiple occurrences of word+space
]               # Literal closing bracket (no need to escape outside character class)

上面将匹配括号之间的换行符。如果你不想这样,那么使用

\[\ *((?<word>[^[\]\s]+)\ *)+]

【讨论】:

    猜你喜欢
    • 2021-04-01
    • 1970-01-01
    • 2019-10-11
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-30
    相关资源
    最近更新 更多