反转一组相当复杂的正则表达式

Posted

技术标签:

【中文标题】反转一组相当复杂的正则表达式【英文标题】:Inverting a rather complex set of regexes 【发布时间】:2015-01-20 23:05:03 【问题描述】:

我对正则表达式有点陌生,我在网上找到的解决方案都没有帮助/奏效。

我正在处理 javascript 中的单行字符串,它将包含五种类型的数据。

“#”后跟六个数字/字母(html 颜色)(/#....../g) 正斜杠后跟任意几个特定字符 (/\/(\+|\^|\-|#|!\+|_|@|\*|%|&|~)/g) 一个“$”后跟一个字母序列和一个“|” (/\$([^\|]+)/g) 一个“|”一个人 (/\|/g) 不属于任何这些类别的字母数字字符

问题是,我有正则表达式来匹配前四个类别,这很重要。 问题是我需要一个正则表达式,用于将前四个正则表达式不匹配的所有字符替换为单个字符,例如“§”。

例子:

This#00CC00 is green$Courier| and /^mono|spaced

§§§§#00CC00§§§§§§§§§$Courier|§§§§§/^§§§§|§§§§§§

我知道我可能以错误的方式解决这个问题,我对正则表达式相当陌生。 本质上,我如何制作一个表示“任何与正则表达式 x、y 或 z 不匹配的东西”的正则表达式?

感谢您的宝贵时间。

【问题讨论】:

所以如果你的字符串是:"#1234567" 它应该改为:"#123456§"? 是的,我会清除与要替换的四个正则表达式不匹配的所有内容。在this site 上测试正则表达式/#......|\/(\+|\^|\-|#|!\+|_|@|\*|%|&|~)|\$([^\|]+)\||\|/g 正是我的意思。我希望所有被选中的东西都不会被选中,反之亦然。 【参考方案1】:

使用这种模式

((#\w6|\/[\/\(\+\^\-]|\$\w+\||\|)*).

并替换为$1§ 缺点是您保留的模式必须后跟至少一个字符Demo

(                   # Capturing Group (1)
  (                 # Capturing Group (2)
    #               # "#"
    \w              # <ASCII letter, digit or underscore>
    6             # (repeated 6 times)
    |               # OR
    \/              # "/"
    [\/\(\+\^\-]    # Character Class [\/\(\+\^\-]
    |               # OR
    \$              # "$"
    \w              # <ASCII letter, digit or underscore>
    +               # (one or more)(greedy)
    \|              # "|"
    |               # OR
    \|              # "|"
  )                 # End of Capturing Group (2)
  *                 # (zero or more)(greedy)
)                   # End of Capturing Group (1)
.                   # Any character except line break  

从 Regex101 复制的代码

var re = /((#\w6|\/[\/\(\+\^\-]|\$\w+\||\|)*)./gm;   
var str = 'This#00CC00 is green$Courier| and /^mono|spaced|\n';  
var subst = '$1§';   
var result = str.replace(re, subst);

【讨论】:

正则表达式似乎适用于您提供的链接,是的。现在,这听起来可能很愚蠢,但我如何使用 JavaScript 进行这样的替换? 不得不做一点小改动,改成/((#\w6|\/[\/\(\+\^\-]|\$.+\||\|)*)./gm。除此之外,就像一个魅力!谢谢! @BrunoPaschoalinoto,你可能想把它改成/((#\w6|\/[\/\(\+\^\-]|\$.+?\||\|)*)./gm,注意惰性操作符? 哦,是的。再次感谢!【参考方案2】:

这不如有效的正则表达式有效,但它确实有效。基本上,它会获取所有匹配项并用§ 字符填充之间的部分。一件好事是您不必成为正则表达式天才即可对其进行更新,因此希望更多人可以使用它。

var str = 'This#00CC00 is green$Courier| and /^mono|spaced';
var patt=/#(\d|\w)6|\/(\+|\^|\-|#|!\+|_|@|\*|%|&|~)|\$([^\|]+)\||\|/g;
var ret = "";

pos = [];
while (match=patt.exec(str)) 
    pos.push(match.index);
    pos.push(patt.lastIndex);
    console.log(match.index + ' ' + patt.lastIndex);


for (var i=0; i<pos.length; i+=2) 
    ret += Array(1+pos[i]- (i==0 ? 0 : pos[i-1])).join("§");
    ret += str.substring(pos[i], pos[i+1]);

ret += Array(1+str.length-pos[pos.length-1]).join("§");

document.body.innerHTML = str +"<br>"+ret;

console.log(str);
console.log(ret);

demo here

【讨论】:

以上是关于反转一组相当复杂的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

这个正则表达式替换如何反转字符串?

正则表达式基础

正则表达式

java里正则表达式是啥意思啊

如何在熊猫过滤器函数中反转正则表达式

那些年我们一起走过正则表达式的坑