我如何在这个正则表达式中自己编写一个转义字符?

时间:2019-06-14 18:24:20

标签: javascript regex escaping regex-lookarounds

我想要实现一个功能,该功能从“ str1 | str2 @ str3”之类的输入字符串中将各个字符串作为数组输出:

function myFunc(string) { ... }

对于输入string,只需要存在str1str2str3(及其定界符)都是可选的。为此,我已经编写了执行某种拆分的正则表达式。我不能进行(常规)拆分,因为分隔符是不同的字符,并且str1,str2和str3的顺序也很重要。这有点适合我的正则表达式模式。现在,我正在努力扩展该模式,以便可以使用\ |来转义两个定界符。或\ @。

我该如何最好地解决这个问题?

var strings = [
  'meaning',
  'meaning|description',
  'meaning@id',
  'meaning|description@id',
  '|description',
  '|description@id',
  '@id',
  'meaning@id|description',
  'sub1\\|sub2',
  'mea\\|ning|descri\\@ption',
  'mea\\@ning@id',
  'meaning|description@identific\\|\\@ation'
];

var pattern = /^(\w+)(?:\|(\w*))?(?:\@(\w*))?$/ // works without escaping
console.log(pattern.exec(strings[3]));

根据问题定义,字符串0-3和8-11应该有效,其余字符串则无效。 myFunc(strings[3])并应返回['meaning','description','id'],而myFunc(strings[8])应返回[sub1\|sub2,null,null]

3 个答案:

答案 0 :(得分:0)

我的猜测是,您希望拆分所有字符串,为此,我们可能会将这些分隔符添加到char类中,类似于:

([|@\\]+)?([\w]+)

如果不这样做,我们可能希望这样做以进行验证,否则随着组合的增加,我们的验证将变得非常复杂。

const regex = /([|@\\]+)?([\w]+)/gm;
const str = `meaning
meaning|description
meaning@id
meaning|description@id
|description
|description@id
@id
meaning@id|description
sub1\\|sub2
mea\\|ning|descri\\@ption
mea\\@ning@id
meaning|description@identific\\|\\@ation`;
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}`);
    });
}

Demo

答案 1 :(得分:0)

您需要允许\\[|@]\w旁边的模式中,将\w替换为(?:\\[@|]|\w)模式:

var strings = [
  'meaning',
  'meaning|description',
  'meaning@id',
  'meaning|description@id',
  '|description',
  '|description@id',
  '@id',
  'meaning@id|description',
  'sub1\\|sub2',
  'mea\\|ning|descri\\@ption',
  'mea\\@ning@id',
  'meaning|description@identific\\|\\@ation'
];

var pattern = /^((?:\\[@|]|\w)+)(?:\|((?:\\[@|]|\w)*))?(?:@((?:\\[@|]|\w)*))?$/;
for (var s of strings) {
   if (pattern.test(s)) {
     console.log(s, "=> MATCHES");
   } else {
     console.log(s, "=> FAIL");
   }
}

模式详细信息

  • ^-字符串开头
  • ((?:\\[@|]|\w)+)-第1组:\的1个或更多重复,后跟@|或单词char
  • (?:\|((?:\\[@|]|\w)*))?-与1个或0个匹配项匹配的可选组
    • \|-一个|字符
    • ((?:\\[@|]|\w)*)-第2组:\的0个或多个重复,后跟@|或单词char
  • (?:@((?:\\[@|]|\w)*))?-与1个或0个匹配项匹配的可选组
    • @-一个@字符
    • ((?:\\[@|]|\w)*)第3组:\的0个或多个重复,后跟@|或单词char
  • $-字符串的结尾。

答案 2 :(得分:0)

看起来像您要找的东西吗?

((?:\\@|\\\||[^\|@])*)*

说明: 匹配包括"\@""\|""@""|"以外的任何字符的所有集合。

https://regexr.com/4fr68