负向后查找与转义字符不匹配,在转义反斜杠上失败

时间:2019-08-05 15:49:04

标签: javascript regex typescript escaping negative-lookbehind

说我想在任何分隔符char处分割字符串,但不能在转义的char处分割,我通常可以使用负数lookbehind和string.split(regex)。

例如:

const regex = /(?<!\\)\,/;
'abc,def'.split(regex); 
'abc\\,def'.split(regex); 

,中的abc,def处分割,但不在abc\,def中分割。很好!

但是,如果分隔符本身是反斜杠,则后面的负向外观似乎无法按预期工作:

const regex = /(?<!\\)\\/;
'abc\\def'.split(regex); 
'abc\\\\def'.split(regex); 

\abc\def的第一个abc\\def处拆分。

天真地,我希望后面的负向查找不匹配\之后的\

请参阅:https://regex101.com/r/ozkZR1/1

如何在不与反斜杠或换行符等特殊字符分开的任何未转义字符处实现string.split(regex)?

2 个答案:

答案 0 :(得分:1)

天真解决方案

在分隔符与定界符相同的情况下,可以在分隔符之后的否定前瞻,位于否定后视之上:

/(?<!\\)\\(?!\\)/

注意事项

此方法存在很多问题,我不建议使用正则表达式解决它,尤其不建议允许分隔符和转义符相同。

  • 使用,作为分隔符,字段末尾的文字字符将欺骗正则表达式,例如abc\\,def不会被拆分。
  • 使用\作为分隔符和转义符,您不能有空字段:abc,,def将是三个字段,包括一个空字段,但是abc\\def只会是一个字段。
  • abc\\\def呢?在第一个字段的末尾或第二个字段的开头是否有文字\?无论哪种方式,我的正则表达式都不会分裂。

如果您愿意从字面上禁止在边界使用转义字符,并且不允许使用空字段,那么当转义符和分隔符相同时,我的正则表达式将起作用;在其他情况下,您的正则表达式将起作用。

否则,我建议使用另一种解决方案,其中从左到右分析字符串,在遇到转义符时解释转义符,并在看到未转义的分隔符时进行拆分,以使abc\\,def被正确拆分。

答案 1 :(得分:0)

解决方案是撤消操作:

我可以寻找分隔的字符序列,而不是寻找分隔符。因此,在使用,分隔符的情况下,我会寻找:((\\,)|[^,])([^,]*?(\\,)?)*:转义的逗号或非逗号字符,后跟任意数量(可能为空)的一组非逗号(不愿意,所以它不能捕获转义的\,其后跟一个可选的转义逗号。

let separator = ','; // get from sanitized input
separator = separator === '\\' ? '\\\\' : separator;
const groups = new RegExp(`((\\\\${separator})|[^${separator}])([^${separator}]*?(\\\\${separator})?)+`, 'g');
let columns = line.match(groups);

此方法适用于,\作为分隔符,并且不会分别在\,\\上拆分。

该表达式最难的部分是正确处理所有转义符。