2

我不明白如何解决以下问题:

我有输入字符串“aaaabaa”,我正在尝试搜索字符串“aa”(我正在寻找字符的位置)预期结果是 0 1 2 5

  • 啊啊
  • 啊啊啊啊_
  • 啊啊啊_
  • 啊啊啊啊

我已经使用另一种方法(非RegEx)解决了这个问题。但我需要一个 RegEx 我是 RegEx 的新手,所以谷歌搜索真的帮不了我。任何帮助表示赞赏!谢谢!

PS我试过用(aa)*"\b(\w+(aa))*\w+"但那些表达是错误的

4

3 回答 3

2

您可以通过使用前瞻来解决这个问题

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

于 2012-04-24T08:56:57.000 回答
0

以下代码应适用于任何正则表达式,而无需更改实际表达式:

        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 方法会在尝试下一个匹配之前前进一个字符。这种行为保证了正则表达式引擎将通过字符串进行。否则,由于空匹配不会导致任何向前移动,因此下一个匹配将在与上一个匹配完全相同的位置开始,并且会重复匹配相同的空字符串。

于 2012-04-24T13:55:09.203 回答
-1

试试这个:

如何在 Java 中使用正则表达式查找重复字符?

它在 java 中,但是有正则表达式和非正则表达式的方式。C# Regex 与 Java 方式非常相似。

于 2012-04-24T08:56:46.647 回答