正则表达式在字符串中多次匹配

RegEx Match multiple times in string

提问人:Mike Mengell 提问时间:2/4/2011 更新时间:5/6/2019 访问量:56789

问:

我正在尝试从字符串中提取介于 << 和 >> 之间的值。但它们可能会发生多次。

谁能帮忙用正则表达式来匹配这些;

this is a test for <<bob>> who like <<books>>
test 2 <<frank>> likes nothing
test 3 <<what>> <<on>> <<earth>> <<this>> <<is>> <<too>> <<much>>.

然后,我想foreachGroupCollection以获取所有值。

任何帮助都得到了极大的帮助。 谢谢。

C# 正则表达式

评论


答:

3赞 MarioVW 2/4/2011 #1

您可以尝试以下方法之一:

(?<=<<)[^>]+(?=>>)
(?<=<<)\w+(?=>>)

但是,您必须迭代返回的 MatchCollection。

0赞 Gabriel Magana 2/4/2011 #2

像这样的东西:

(<<(?<element>[^>]*)>>)*

这个程序可能很有用:

http://sourceforge.net/projects/regulator/

60赞 heijp06 2/4/2011 #3

使用正面向前看和向后看断言来匹配尖括号,用于匹配这些括号之间尽可能短的字符序列。通过迭代方法返回的值来查找所有值。.*?MatchCollectionMatches()

Regex regex = new Regex("(?<=<<).*?(?=>>)");

foreach (Match match in regex.Matches(
    "this is a test for <<bob>> who like <<books>>"))
{
    Console.WriteLine(match.Value);
}

DotNetFiddle 中的 LiveDemo

评论

1赞 Mike Mengell 2/4/2011
没有双关语的意思,但这正是我所追求的。谢谢你的快速回复。
4赞 Wiktor Stribiżew 5/6/2019 #4

虽然 Peter 的回答是使用环视进行左右上下文检查的一个很好的例子,但我还想添加一种 LINQ (lambda) 方法来访问匹配/组,并展示如何使用简单的数字捕获组,当您只想提取模式的一部分时,这些会派上用场:

using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;

// ...

var results = Regex.Matches(s, @"<<(.*?)>>", RegexOptions.Singleline)
            .Cast<Match>()
            .Select(x => x.Groups[1].Value);

与 Peter 编译的方法相同,其中通过以下方式访问整个匹配值:regexMatch.Value

var results = regex.Matches(s).Cast<Match>().Select(x => x.Value);

注意

  • <<(.*?)>>是正则表达式匹配,然后尽可能少地(由于非贪婪量词)捕获任何 0 或多个字符到组 1 中,然后匹配<<*?>>
  • RegexOptions.Singleline也使匹配换行符 (LF) 字符(默认情况下不匹配它们).
  • Cast<Match>()将 match 集合转换为您可以使用 lambda 进一步访问的IEnumerable<Match>
  • Select(x => x.Groups[1].Value)仅返回当前匹配对象中的组 1 值x
  • 请注意,您可以通过在 之后添加 或 来进一步创建所获得值的数组列表。.ToList().ToArray()Select

演示 C# 代码中,生成组 1 值的逗号分隔字符串:string.Join(", ", results)

var strs = new List<string> { "this is a test for <<bob>> who like <<books>>",
                              "test 2 <<frank>> likes nothing",
                              "test 3 <<what>> <<on>> <<earth>> <<this>> <<is>> <<too>> <<much>>." };
foreach (var s in strs) 
{
    var results = Regex.Matches(s, @"<<(.*?)>>", RegexOptions.Singleline)
            .Cast<Match>()
            .Select(x => x.Groups[1].Value);
    Console.WriteLine(string.Join(", ", results));
}

输出:

bob, books
frank
what, on, earth, this, is, too, much