Regex 将字符串模式与随机开始和/或结束匹配

Regex 将字符串模式与随机开始和/或结束匹配,regex,algorithm,Regex,Algorithm,假设我有以下构造: pattern = 'RepeatingMessage' searchString = 'Aai23epjsditssageRepeatingMessageRepeatingMessageRepeatingMessageRepAsdjigrjiegj' 我怎样才能生成一个剪切的函数 'ssageRepeatingMessageRepeatingMessageRepeatingMessageRep' 可靠地,这样重复消息的开始和结束可以是随机的 因此,它也可能是: 'sfd

假设我有以下构造:

pattern = 'RepeatingMessage'
searchString = 'Aai23epjsditssageRepeatingMessageRepeatingMessageRepeatingMessageRepAsdjigrjiegj'
我怎样才能生成一个剪切的函数

'ssageRepeatingMessageRepeatingMessageRepeatingMessageRep'
可靠地,这样重复消息的开始和结束可以是随机的

因此,它也可能是:

'sfdsfu338843ufsingMessageRepeatingMessageRepeatingMessafuaz8792afsmssage'
在你剪的第二根弦上

'ingMessageRepeatingMessageRepeatingMessa'

提前感谢

我的回答基于一个假设,即必须匹配的字符数最少

步骤1:构建一个状态机来计算匹配的字符数。此状态机将是循环的。构建此状态机时,应在数组中为每个节点编制索引。例如:

Node Nr:  0    1    2    3    4    5    6    7    8    ...
Node   :  R -> e -> p -> e -> a -> t -> i -> n -> g -> ...
Index:
'R' -> Node 0
'e' -> Node 1, 3, ...
然后在两种状态之间切换:

  • 不消耗:对于索引中的每个节点,输入当前字母并遍历,直到达到最小长度。如果达到最小长度,则输入消耗状态,否则移动到下一个字母
  • 消费:持续消费,直到状态机爆发。切换到非消费状态
  • 测试代码:

    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class RepeatingMatcher
    {
        public static String match(String pattern, String input)
        {
            Map<Character, List<PatternNode>> index = PatternNode.buildPattern(pattern);
            
            StringBuilder filteredInput = new StringBuilder();
            
            for (int i = 0; i < input.length(); i++)
            {
                char c = input.charAt(i);
                List<PatternNode> idxl = index.get(c);
                if (idxl != null)
                {
                    boolean looking = true;
                    for (int j = 0; looking && j < idxl.size(); j ++)
                    {
                        int matchCnt = idxl.get(j).consume(input, i, 0);
                        if (matchCnt >= pattern.length())
                        {
                            // - 1 because the for loop will increment it.
                            i += matchCnt - 1;
                            looking = false;
                        }
                    }
                    
                    if (looking)
                    {
                        filteredInput.append(c);
                    }
                }
                else
                {
                    filteredInput.append(c);
                }
            }
            
            return filteredInput.toString();
        }
    
        private static class PatternNode
        {
            private final char patternChar;
            private PatternNode next;
    
            PatternNode(char patternChar)
            {
                this.patternChar = patternChar;
            }
    
            int consume(String s, int idx, int cnt)
            {
                if (patternChar == s.charAt(idx))
                {
                    cnt = cnt + 1;
                    if (next != null)
                    {
                        cnt = next.consume(s, idx + 1, cnt);
                    }
                }
    
                return cnt;
            }
    
            static Map<Character, List<PatternNode>> buildPattern(String pattern)
            {
                Map<Character, List<PatternNode>> index = new HashMap<>();
    
                char c = pattern.charAt(0);
                PatternNode root = new PatternNode(c);
                List<PatternNode> idxl = index.getOrDefault(c, new ArrayList<>());
                index.put(c, idxl);
                idxl.add(root);
                PatternNode curr = root;
                for (int i = 1; i < pattern.length(); i++)
                {
                    c = pattern.charAt(i);
                    curr.next = new PatternNode(c);
                    curr = curr.next;
                    idxl = index.getOrDefault(c, new ArrayList<>());
                    index.put(c, idxl);
                    idxl.add(curr);
                }
                curr.next = root;
    
                return index;
            }
        }
    
    }
    
    
    导入java.util.ArrayList;
    导入java.util.HashMap;
    导入java.util.List;
    导入java.util.Map;
    公共类重复匹配器
    {
    公共静态字符串匹配(字符串模式、字符串输入)
    {
    映射索引=PatternNode.buildPattern(pattern);
    StringBuilder filteredInput=新建StringBuilder();
    对于(int i=0;i=pattern.length())
    {
    //-1,因为for循环将增加它。
    i+=matchCnt-1;
    看=假;
    }
    }
    如果(看)
    {
    filteredInput.append(c);
    }
    }
    其他的
    {
    filteredInput.append(c);
    }
    }
    返回filteredInput.toString();
    }
    私有静态类模式节点
    {
    私有最终字符模式字符;
    下一个是私有模式节点;
    PatternNode(char patternChar)
    {
    this.patternChar=patternChar;
    }
    整数消耗(字符串s、整数idx、整数cnt)
    {
    if(patternChar==s.charAt(idx))
    {
    cnt=cnt+1;
    如果(下一步!=null)
    {
    cnt=next.consume(s,idx+1,cnt);
    }
    }
    返回cnt;
    }
    静态映射构建模式(字符串模式)
    {
    映射索引=新的HashMap();
    字符c=模式字符(0);
    PatternNode根=新PatternNode(c);
    List idxl=index.getOrDefault(c,newArrayList());
    指数put(c,idxl);
    添加(根);
    PatternNode curr=根节点;
    对于(int i=1;i
    好的,谢谢您的回复。我无法让java代码为我工作,但我制作了一个简单的脚本,似乎可以实现这一点。它从模式索引中向前和向后搜索,然后检出:(powershell)


    该问题包含regex标记。我不会完全根据您的用例来建议这种方法,但我还是解决了它。这里是一个更简单、更可读的正则表达式,用于关键字“word”:

    以下是解决问题的完整正则表达式:

    ((((((((((((((((R)?e)?p)?e)?a)?t)?i)?n)?g)?M)?e)?s)?s)?a)?g)?e)?(RepeatingMessage)+(R(e(p(e(a(t(i(n(g(M(e(s(s(a(g(e)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
    

    模式是否在字符串中仅连续出现一次,或者是否可以有类似“EssagerepeatingMessageRepoooooAgerepeatingMessagere”的内容?是否有必须匹配的最小长度?例如,RepeatingMessage包含“a”,而原始字符串“Aai23epjsditssageRepeatingMessageRepeatingMessageRepeatingMessageRepAsdjigrjiegj”在第二个位置包含“a”。为什么这些不匹配?是的,让我们说最小字符是整个模式至少让我们说最小字符是整个模式。你能用你喜欢的语言给出类似的代码吗?我明白这个概念,但我可能很难实现它们。我尝试了你的代码,但无法让它工作。我做了一个脚本,现在为我做。我在一个回复中发布了它。我对它进行了测试,并修复了一些打字错误(在2或3个位置交换了输入和模式)和一个off-by-1错误。它现在运行良好,尽管我希望您能调试那么多。这很好,它可以很好地创建一个函数,为特定字符串生成正则表达式。虽然在“epeatingMessa”这样的情况下,当完整字符串没有出现时,它会失败。如果这是所需的行为,您可以将中心“+”替换为“*”
    ((((w)?o)?r)?d)?(word)+(w(o(r(d)?)?)?)?
    
    ((((((((((((((((R)?e)?p)?e)?a)?t)?i)?n)?g)?M)?e)?s)?s)?a)?g)?e)?(RepeatingMessage)+(R(e(p(e(a(t(i(n(g(M(e(s(s(a(g(e)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?