我试图使regex正常工作,但不能(可能是因为我对regex相当陌生)。
这就是我想要做的:
考虑此文本:一个单词,决斗。石灰说再见。
想要的匹配项:一个单词,决斗。 石灰 说再见。
如标题中先前所述,我想使连续的单词匹配,一个单词以(例如)以“ t”结尾,另一个单词以“ t”开头,不区分大小写。
我最接近答案的是这个表达式[^a-z][a-z]*([a-z])[^a-z]+\1[a-z]*([a-z])[^a-z]+\2[a-z]*[^a-z]
答案 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
-单词边界。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+倍匹配)
近距离浏览)
关闭非捕获组请注意,匹配[a-zA-Z]
的范围很小。您可以改用\w
或\p{L}
。