【问题标题】:RegEx for matching everything except a repeating char at start and endRegEx 用于匹配除开头和结尾的重复字符之外的所有内容
【发布时间】:2019-05-11 08:45:42
【问题描述】:

我有一个字符串模式,示例如下。

AA4grgrsragrga4334grAA

AAA4323425AAA

AAAAAA%%%AAAAAA

前导 'A's 和尾随 As 总是成对出现。

我试过了:

A+.+A+

不知道如何在 REGEX 中配对前导 As 和尾随 As。

【问题讨论】:

  • 您使用的是哪种正则表达式定义?答案可能取决于此。
  • 那些*s 是否在字符串的开头和结尾,或者它们是否试图格式化问题的代码?
  • @CertainPerformance 是的,它们是斜体。已更正

标签: regex regex-negation regex-lookarounds regex-group regex-greedy


【解决方案1】:

捕获组中的初始As,然后重复匹配任何字符后跟非A,然后再次反向引用第一个组,然后是字符串的结尾:

^(A+).*[^A]\1$

https://regex101.com/r/81ge2k/2

如果A 只会出现在字符串的开头和结尾,您可以使用否定字符集来代替:

^(A+)[^A]*\1$

如果输入字符串应该跨越整行,请确保使用字符串开头和结尾锚点,否则模式可能匹配不匹配的As。

【讨论】:

  • 你确定这不会匹配AAzzAAA
  • 好点,谢谢,需要确保尾随 As 之前的最后一个字符不是 A
【解决方案2】:

如果您还想在 AA 或 AAAAAA 等字符串的开头和结尾匹配成对的 A,也可以使用 AAteAstAA,您可以使用交替:

^(A+)(?:[^A].*[^A]|[^A])?\1$

关于模式

  • ^ 字符串开始
  • (A+)第一组匹配1+A的抓拍
  • (?:非捕获组
    • [^A].*[^A] 不匹配 A,除换行符以外的任何字符 0+ 次,然后又不匹配 A
    • |或者
    • [^A]不匹配A
  • )?关闭非捕获组并使其可选
  • \1 反向引用第 1 组
  • $字符串结束

Regex demo

如果AAA也可以匹配你可以使用

^(A+)(?:[^A].*[^A]|.)?\1$

Regex demo

【讨论】:

    【解决方案3】:

    This expressionA+ 之间有一个简单的捕获组,从左到右滑动每个非 A 字符:

    A+([^A]*)A+
    


    如果你想捕获A+,你可以简单地用两个捕获组()包装它们,类似于this expression

    (A+)([^A]*)(A+)
    


    如果您不想匹配 A 字符,那么您可以简单地将它们从 the expression 中删除:

    [^A]*
    

    但是,如果中间有 A,这将不匹配,需要修改。


    正则表达式描述图

    此图可视化表达式,如果您愿意,可以在此link 中测试其他表达式:

    JavaScript 测试

    const regex = /(A+)([^A]*)(A+)/gm;
    const str = `AA4grgrsragrga4334grAA
    AAA4323425AAA
    AAAAAA%%%AAAAAA`;
    let m;
    
    while ((m = regex.exec(str)) !== null) {
        // This is necessary to avoid infinite loops with zero-width matches
        if (m.index === regex.lastIndex) {
            regex.lastIndex++;
        }
        
        // The result can be accessed through the `m`-variable.
        m.forEach((match, groupIndex) => {
            console.log(`Found match, group ${groupIndex}: ${match}`);
        });
    }

    (A+)([^A]*)(A+)的基本性能测试

    此 JavaScript sn-p 返回运行时 100 万次 for 循环以提高性能。

    const repeat = 1000000;
    const start = Date.now();
    
    for (var i = repeat; i >= 0; i--) {
    	const string = 'AAAAAAAAAanyThingElse4grgrsragrga4334grAAAA';
    	const regex = /(A+)([^A]*)(A+)/gm;
    	var match = string.replace(regex, "\nGroup #1: $1\nGroup #2: $2\nGroup #3: $3\n");
    }
    
    const end = Date.now() - start;
    console.log("YAAAY! \"" + match + "\" is a match ??? ");
    console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. ? ");

    A+([^A]*)A+的基本性能测试

    const repeat = 1000000;
    const start = Date.now();
    
    for (var i = repeat; i >= 0; i--) {
    	const string = 'AAAAAAAAAanyThingElse4grgrsragrga4334grAAAA';
    	const regex = /A+([^A]*)A+/gm;
    	var match = string.replace(regex, "Group #1: $1");
    }
    
    const end = Date.now() - start;
    console.log("YAAAY! \"" + match + "\" is a match ??? ");
    console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. ? ");

    【讨论】:

    • 你的正则表达式匹配 AA***A 但它不应该。 “前导 'A's 和尾随 As 总是成对出现。”
    猜你喜欢
    • 1970-01-01
    • 2011-09-06
    • 2019-09-29
    • 2017-02-01
    • 2022-06-28
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    • 2011-01-25
    相关资源
    最近更新 更多