如何在字符串中查找所有匹配项

4
假设我有以下字符串:
xx##a#11##yyy##bb#2##z
我试图检索所有出现的“##something#somethingElse##”
(在我的字符串中,我想要2个匹配:##a#11##和##bb#2##)
我尝试使用如下代码获取所有匹配:
Regex.Matches(MyString, ".*(##.*#.*##).*")

但是它只检索出了一条完整的匹配结果。如何获取字符串中的所有匹配结果呢?谢谢。
2个回答

4

由于您的模式以.*开头和结尾,因此只会得到整行匹配。此外,在您的模式中,#之间的.*过于贪婪,并且在单行上遇到时会将所有预期匹配抓取到一个匹配项中。

您可以使用

var results = Regex.Matches(MyString, "##[^#]*#[^#]*##")
    .Cast<Match>()
    .Select(m => m.Value)
    .ToList();

请参考下面的内容:

请看正则表达式演示

注意:如果##和#之间必须至少有一个字符,则将*量词(匹配0个或多个字符)替换为+量词(匹配1个或多个字符)。

注2:若要避免在####..#....#####内匹配,可添加环视:"(?<!#)##[^#]+#[^#]+##(?!#)"

模式详细信息

  • ## - 2个 # 符号
  • [^#]* / [^#]+ - 匹配除 # 外的 0 个或多个字符 (或 1 个或多个字符) 的负字符类
  • # - 单个#
  • [^#]* / [^#]+ - 匹配 0 个或多个字符 (或 1 个或多个字符) ,不包括 #
  • ## - 双#符号。

BONUS:要获取##和##内的内容,请使用捕获组,用非转义的圆括号括起需要提取的模式部分,并抓取Match.Groups[1].Value

var results = Regex.Matches(MyString, @"##([^#]*#[^#]*)##")
    .Cast<Match>()
    .Select(m => m.Groups[1].Value)
    .ToList();

*的问题在于它会匹配##### - abc123
@abc123:这完全取决于要求,* 可以替换为 +。我还添加了更多的调整选项,详见注释 - Wiktor Stribiżew
根据您的帮助,我也成功地得到了未包含##的匹配项(即获取a#1而不是##a#1##)。我使用了这个模式:[^##][^#]#[^#][^##]。 - Nir
但是,你需要使用一个捕获组,让我来展示。 - Wiktor Stribiżew

4

Regex101

Regex.Matches(MyString, "(##[^#]+#[^#]+##)")


这段代码使用正则表达式从字符串中匹配类似于"##内容#"的格式。
(##[^#]+#[^#]+##)

描述

1st Capturing Group (##[^#]+#[^#]+##)
    ## matches the characters ## literally (case sensitive)
    Match a single character not present in the list below [^#]+
        + Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
    # matches the character # literally (case sensitive)
    # matches the character # literally (case sensitive)
    Match a single character not present in the list below [^#]+
        + Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
    # matches the character # literally (case sensitive)
    ## matches the characters ## literally (case sensitive)

正则表达式可视化

Debuggex演示


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接