我不明白如何解决以下问题:
我有输入字符串“aaaabaa”,我正在尝试搜索字符串“aa”(我正在寻找字符的位置)预期结果是 0 1 2 5
- 啊啊啊
- 啊啊啊啊_
- 啊啊啊_
- 啊啊啊啊
我已经使用另一种方法(非RegEx)解决了这个问题。但我需要一个 RegEx 我是 RegEx 的新手,所以谷歌搜索真的帮不了我。任何帮助表示赞赏!谢谢!
PS我试过用(aa)*
,"\b(\w+(aa))*\w+"
但那些表达是错误的
您可以通过使用前瞻来解决这个问题
a(?=a)
将找到后跟另一个“a”的每个“a”。
如果您想更一般地执行此操作
(\p{L})(?=\1)
这将找到后跟相同字符的每个字符。每个找到的字母都存储在一个捕获组中(因为括号周围),然后这个捕获组通过使用(其中存储了匹配字符)被正向超前断言(the )重用(?=...)
\1
\1
\p{L}
是“字母”类别的 unicode 代码点
代码
String text = "aaaabaa";
Regex reg = new Regex(@"(\p{L})(?=\1)");
MatchCollection result = reg.Matches(text);
foreach (Match item in result) {
Console.WriteLine(item.Index);
}
输出
0
1
2
5
以下代码应适用于任何正则表达式,而无需更改实际表达式:
Regex rx = new Regex("(a)\1"); // or any other word you're looking for.
int position = 0;
string text = "aaaaabbbbccccaaa";
int textLength = text.Length;
Match m = rx.Match(text, position);
while (m != null && m.Success)
{
Console.WriteLine(m.Index);
if (m.Index <= textLength)
{
m = rx.Match(text, m.Index + 1);
}
else
{
m = null;
}
}
Console.ReadKey();
它使用该选项来更改每个连续搜索的正则表达式搜索的开始索引。实际问题来自于 Regex 引擎在默认情况下总是会在前一个匹配之后继续搜索。因此,它永远不会在另一个匹配项中找到可能的匹配项,除非您通过使用 Look ahead 构造或手动设置开始索引来指示它。
另一个相对简单的解决方案是将整个表达式保持向前看:
string expression = "(a)\1"
Regex rx2 = new Regex("(?=" + expression + ")");
MatchCollection ms = rx2.Matches(text);
var indexes = ms.Cast<Match>().Select(match => match.Index);
这样一来,引擎将自动为找到的每个匹配项将索引推进一个。
从文档:
当通过调用 NextMatch 方法重复匹配尝试时,正则表达式引擎会给予空匹配特殊处理。通常,NextMatch 会在前一个匹配停止的位置开始搜索下一个匹配。但是,在空匹配之后,NextMatch 方法会在尝试下一个匹配之前前进一个字符。这种行为保证了正则表达式引擎将通过字符串进行。否则,由于空匹配不会导致任何向前移动,因此下一个匹配将在与上一个匹配完全相同的位置开始,并且会重复匹配相同的空字符串。