每隔一次匹配

Shy*_*yam 44 regex

有没有办法指定正则表达式来匹配字符串中每个第二次出现的模式?

例子

  • 寻找一个对字符串abcdabcd应该找到在5位出现一次
  • 搜索ab 反对字符串abcdabcd应该在第5位找到一个匹配项
  • 搜索dab 反对字符串abcdabcd应该找不到任何事件
  • 搜索一个反对字符串aaaa应该在第2和第4位找到两个匹配项

Ale*_*ett 61

使用分组.

foo.*?(foo)
Run Code Online (Sandbox Code Playgroud)

  • 这确实需要更好的解释 (17认同)

Il-*_*ima 9

假设你想要的模式是abc + d.您希望在字符串中匹配此模式的第二个匹配项.

您将构建以下正则表达式:

abc+d.*?(abc+d)
Run Code Online (Sandbox Code Playgroud)

这将匹配形式的字符串: <your-pattern>...<your-pattern>.既然我们正在使用不情愿的限定符*?我们很安全,两者之间不可能有另一场比赛.使用几乎所有正则表达式实现提供的匹配器组,然后将在括号内的组中检索您想要的字符串.


Pat*_*ick 6

会不会喜欢

(pattern.*?(pattern))*
Run Code Online (Sandbox Code Playgroud)

为你工作?

编辑:

这样做的问题是它使用了非贪婪的 operator *?,这可能需要沿字符串进行大量回溯,而不仅仅是查看每个字母一次。这对您来说意味着对于较大的间隙,这可能会很慢。


Wal*_*ssa 6

如果您正在使用C#,您可以立即获得所有匹配,即.使用Regex.Matches()返回MatchCollection(检查项目的索引,索引%2!= 0).

如果你想找到替换它的出现,请使用Regex.Replace()中一个使用MatchEvaluator的重载,例如Regex.Replace(String,String,MatchEvaluator,这里是代码:

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

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = "abcdabcd";

            // Replace *second* a with m

            string replacedString = Regex.Replace(
                input,
                "a",
                new SecondOccuranceFinder("m").MatchEvaluator);

            Console.WriteLine(replacedString);
            Console.Read();

        }

        class SecondOccuranceFinder
        {
            public SecondOccuranceFinder(string replaceWith)
            {
                _replaceWith = replaceWith;
                _matchEvaluator = new MatchEvaluator(IsSecondOccurance);
            }

            private string _replaceWith;

            private MatchEvaluator _matchEvaluator;
            public MatchEvaluator MatchEvaluator
            {
                get
                {
                    return _matchEvaluator;
                }
            }

            private int _matchIndex;
            public string IsSecondOccurance(Match m)
            {
                _matchIndex++;
                if (_matchIndex % 2 == 0)
                    return _replaceWith;
                else
                    return m.Value;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)