【问题标题】:Why the output of this regex varies? [duplicate]为什么这个正则表达式的输出会有所不同? [复制]
【发布时间】:2019-05-15 23:40:10
【问题描述】:

我正在尝试根据提供的字符串使用 RegExp() 构造正则表达式。该字符串由请求提供或动态生成。

我有两个不同的输入

1) "te\*" -> 期望移除 '*' 的特殊行为。预期的正则表达式输出应该是 /te\*/g。

2) "te*" -> 使用 0 或多个重复字符 'e' 的特殊行为。预期的正则表达式输出应该是 /te*/g。

new RegExp("te\*") -> /te*/
new RegExp("te*") -> /te*/

我的第一个问题是为什么两个输入的结果是一样的?我想这可能是因为逃避。然后我尝试了

new RegExp("te\\*") -> /te\*/

我在查看doc 后添加了转义。

var escapeString = function (string){
 return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
} 

使用转义函数的结果与不同的结果相同。

escapeString("te\*") -> /te\\*/
escapeString("te*") -> /te\\*/

我尝试通过将两个黑斜线替换为无来进行转义。我不太确定这种转义是否正确。

var unescapeString = function(string){
 return string.replace(/\\\\/g,"");
}

我想知道为什么正则表达式结果没有改变。我不知道应该如何区分这些输入?

有了这种行为,我决定尝试一些事情,比如转义,或者不做非转义输入工作。

1) 首先输入“te\*”

var unescapeString = function(string){
 return string.replace(/\\\\/g,"");
}

var escapeString = function (string){
 return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

var aa = "te\*";

var a1_es = escapeString(aa);
aa_arr = [];
aa_arr.push(a1_es);
console.log("es1 => ", aa_arr);

var aa_es = escapeString(aa_arr[0]);
aa2_arr = [];
aa2_arr.push(aa_es);
console.log("es2 => ", aa2_arr);

var aa_ues = unescapeString(aa2_arr[0]);
aa_uesArr = [];
aa_uesArr.push(aa_ues);
console.log("ues ===>", aa_uesArr);

var rgex = new RegExp(aa_uesArr[0]);

console.log("rgex2 ===> ",rgex )

上述 sn-p 的输出:

es1 =>  [ 'te\\*' ]
es2 =>  [ 'te\\\\\\*' ]
ues ===> [ 'te\\*' ]
rgex2 ===>  /te\*/

我对 First Input 的预期输出很好。

2) 第二个输入“te*”

var actual = "te*";

var unescapeString = function(string){
 return string.replace(/\\\\/g,"");
}

var escapeString = function (string){
 return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

var actual_es1 = escapeString(actual);
actual1_arr = [];
actual1_arr.push(actual_es1);
console.log("es1 => ", actual1_arr);


var actual_es = escapeString(actual1_arr[0]);
actual_arr = [];
actual_arr.push(actual_es);
console.log("es2 => ", actual_arr);


var actual_ues = unescapeString(actual_es);
actual_uesArr = [];
actual_uesArr.push(actual_ues);
console.log("ues ===>", actual_uesArr);

var actualrgex = new RegExp(actual_uesArr[0]);
console.log("actualrgex ===> ",actualrgex );

上述 sn-p 的输出

es1 =>  [ 'te\\*' ]
es2 =>  [ 'te\\\\\\*' ]
ues ===> [ 'te\\*' ]
actualrgex ===>  /te\*/

第二个输入的预期输出变化。它应该是 /te*/。

我想知道我是在这里遗漏了什么还是朝着不同的方向前进。

感谢您对解决此问题的替代方法的任何帮助或建议。感谢您阅读这篇长文!!!

【问题讨论】:

  • 使用RegExp构造函数的字符串时,需要对转义字符进行转义,即new RegExp("te\\*")等价于/te\*/

标签: javascript regex escaping unescapestring


【解决方案1】:

在构建正则表达式之前先检查字符串是什么 所以你注意到\* 在进入正则表达式之前很久就变成了一个* 这是因为 JavaScript 字符串中的反斜杠 \ 行为

var arr = ['te\*', 'te*', 'te\\*'];
arr.forEach(function(s) {
  console.log('s => ', s);
});

如果你想在你的代码 sn-p 中看到它的实际效果:

var escapeString = function (string){
 return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

var arr = ['te\*', 'te*', 'te\\*'];
arr.forEach(function(s) {
  console.log('s => ', s);

  var es1 = escapeString(s);
  console.log('es1 => ', es1);
  console.log('regex1 ===> ', new RegExp(es1));

  var es2 = escapeString(es1);
  console.log('es2 => ', es2);
  console.log('regex2 ===> ', new RegExp(es2));
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多