正则表达式:查找以相同字母结尾的单词,下一个单词以

时间:2019-11-19 21:03:47

标签: c# regex

我试图使regex正常工作,但不能(可能是因为我对regex相当陌生)。

这就是我想要做的:

考虑此文本:一个单词,决斗。石灰说再见。

想要的匹配项:一个单词决斗石灰 再见。

如标题中先前所述,我想使连续的单词匹配,一个单词以(例如)以“ t”结尾,另一个单词以“ t”开头,不区分大小写。

我最接近答案的是这个表达式[^a-z][a-z]*([a-z])[^a-z]+\1[a-z]*([a-z])[^a-z]+\2[a-z]*[^a-z]

2 个答案:

答案 0 :(得分:3)

您可以使用

(?i)\b(?<w>\p{L}+)(?:\P{L}+(?<w>(\p{L})(?<=\1\P{L}+\1)\p{L}*))+\b

请参见regex demo。结果在“ w”组捕获集合中。

详细信息

  • \b-单词边界
  • (?<w>\p{L}+)-组“ w”(单词):1个或更多BMP Unicode字母
  • (?:\P{L}+(?<w>(\p{L})(?<=\1\P{L}+\1)\p{L}*))+-重复1次或更多次
    • \P{L}+-除BMP Unicode字母外的1个或多个字符
    • (?<w>(\p{L})(?<=\1\P{L}+\1)\p{L}*)-组“ w”:
      • (\p{L})-捕获到第1组的一封信
      • (?<=\1\P{L}+\1)-当前位置的左侧,必须与第1组中捕获的字母相同,除了字母和第1组中的字母外,还有1个以上的字符
      • \p{L}*-0个或更多字母
  • \b-单词边界。

enter image description here

C# code demo

var text = "One word, duel. Limes said bye.";
var pattern = @"\b(?<w>\p{L}+)(?:\P{L}+(?<w>(\p{L})(?<=\1\P{L}+\1)\p{L}*))+\b";
var result = Regex.Match(text, pattern, RegexOptions.IgnoreCase)?.Groups["w"].Captures
        .Cast<Capture>()
        .Select(x => x.Value);
Console.WriteLine(string.Join(", ", result)); // => word, duel, Limes, said

一个C# demo version without using LINQ

string text = "One word, duel. Limes said bye.";
string pattern = @"\b(?<w>\p{L}+)(?:\P{L}+(?<w>(\p{L})(?<=\1\P{L}+\1)\p{L}*))+\b";
Match result = Regex.Match(text, pattern, RegexOptions.IgnoreCase);
List<string> output = new List<string>();
if (result.Success) 
{
    foreach (Capture c in result.Groups["w"].Captures)
        output.Add(c.Value);
}
Console.WriteLine(string.Join(", ", output));

答案 1 :(得分:1)

如果一个单词包含至少2个字符az,则可以使用2个捕获组,并在正向前瞻中交替显示,以检查下一个单词是否以最后一个字符开头,或者前一个单词以结束字符开头,当前单词以最后一个字符。

启用不区分大小写的匹配:

\b([a-z])[a-z]*([a-z])\b(?:(?=[,.]? \2)|(?<=\1 \1[a-z]+))
  • \b字边界
  • ([a-z])捕获第1组匹配a-z
  • [a-z]*在两次之间匹配0+次a-z
  • ([a-z])捕获第2组匹配a-z
  • \b字边界
  • (?:非捕获组
    • (?=正向前进,断言右边是
      • [,.]? \2可选的.,空间以及在第2组中捕获的内容
    • )提前关闭
    • |
    • (?<=向后看,断言左边是
      • \1 \1[a-z]+匹配在组1和空间中捕获的内容,并以字符a-z的1+倍匹配
    • )近距离浏览
  • )关闭非捕获组

Regex demo

请注意,匹配[a-zA-Z]的范围很小。您可以改用\w\p{L}

enter image description here