解决旧版浏览器中不支持的后视问题的解决方法?

Workaround for unsupported lookbehind in older browsers?

由于缺乏浏览器支持,我需要将 2 个 lookbehind RegExp 更改为其他内容。

我有这 2 种模式,其中包括回顾:

  1. 匹配模式 '(任何不是 ')': (ie. 'abcdef':) 如果它不在开头字符串或前面有

     /(?<!^|\,)\'[^\']+\'\:/g
    

  2. 匹配模式 '(任何不是 ')', (ie. 'abcdef',) 如果它不在开头字符串或前面有 :

     /(?<!^|\:)\'[^\']+\'\,/g
    

我需要为每个匹配相同事物的模式找到一个模式,但没有回溯。

带回顾的完整代码:

我有一个用户输入,然后我 运行 通过一系列 .replace(),每个输入都有一个 RegExp,以使其匹配特定格式。

var str = "(user input)";
// expected format 1-(infinite) of '(something)':'(something)' ,-seperated
// ie. "'(something)':'(something)','(something)':'(something)','(something)':'(something)'"

// test str for this example (which is clearly not in the right format)
// str = "  '''aaaaaa¤¤¤ 'iiiiii''''mmmmmm:"bbbbbb''nnnnnn   'kkkkkk¤¤¤,'cccccc'jjjjjj¤¤¤'":'dddddd 'gggggg''hhhhhh',llllll''"'eeeeee¤¤¤  '':'ffffff '  "

// replace all " with ' (so I don't have to account for both in following RegExp below)
str = str.replace(/\"/g, "'");
// str = "  '''aaaaaa¤¤¤ 'iiiiii''''mmmmmm:'bbbbbb''nnnnnn   'kkkkkk¤¤¤,'cccccc'jjjjjj¤¤¤'':'dddddd 'gggggg''hhhhhh',llllll''''eeeeee¤¤¤  '':'ffffff '  "

// remove all illegal characters so even if the format doesn't match nothing bad can be done by the user
str = str.replace(/[^a-zA-Z0-9 \-\/\*\+\=\?\&\%\)\(\#$\.\,\:\']/g, '');
// str = "  '''aaaaaa 'iiiiii''''mmmmmm:'bbbbbb''nnnnnn   'kkkkkk,'cccccc'jjjjjj'':'dddddd 'gggggg''hhhhhh',llllll''''eeeeee  '':'ffffff '  "

// trim the string for spaces and characters not ' at beginning and end
str = str.replace(/([^\']+(?!\'))$|^[^\']+(?=\')/g, '');
// str = "'''aaaaaa 'iiiiii''''mmmmmm:'bbbbbb''nnnnnn   'kkkkkk,'cccccc'jjjjjj'':'dddddd 'gggggg''hhhhhh',llllll''''eeeeee  '':'ffffff '"

// remove anything that is either multiple ' (ie. ''') or not ' (ie. abc) around all :
str = str.replace(/\'+[^\']*\:[^\']*\'+/g, "':'");
// str = "'''aaaaaa 'iiiiii'''':'bbbbbb''nnnnnn   'kkkkkk,'cccccc'jjjjjj'':'dddddd 'gggggg''hhhhhh',llllll''''eeeeee  '':'ffffff '"

// remove anything that is either multiple ' (ie. ''') or not ' (ie. abc) around all ,
str = str.replace(/\'+[^\']*\,[^\']*\'+/g, "','");
// str = "'''aaaaaa 'iiiiii'''':'bbbbbb''nnnnnn   ','cccccc'jjjjjj'':'dddddd 'gggggg''hhhhhh',''''eeeeee  '':'ffffff '"

// trim inside ''
str = str.replace(/\'\s+|\s+\'/g, "'");
// str = "'''aaaaaa'iiiiii'''':'bbbbbb''nnnnnn','cccccc'jjjjjj'':'dddddd'gggggg''hhhhhh',''''eeeeee'':'ffffff'"

// let all multiple ' (ie. ''') be 1 '
str = str.replace(/\'+/g, "'")
// str = "'aaaaaa'iiiiii':'bbbbbb'nnnnnn','cccccc'jjjjjj':'dddddd'gggggg'hhhhhh','eeeeee':'ffffff'"

// THE FIRST LOOKBEHIND - let all patterns '(anything not a ')': (ie. 'abcdef':) if it is not at the beginning of the string or preceded by a , be ':
while (str.match(/(?<!^|\,)\'[^\']+\'\:/g)) {
    str= str.replace(/(?<!^|\,)\'[^\']+\'\:/g, "':");
}
// loop 1: // str = "'aaaaaa':'bbbbbb'nnnnnn','cccccc':'dddddd'gggggg'hhhhhh','eeeeee':'ffffff'"
// no more matches so moving on

// THE SECOND LOOKBEHIND - let all patterns '(anything not a ')', (ie. 'abcdef',) if it is not at the beginning of the string or preceded by a : be ',
while (str.match(/(?<!^|\:)\'[^\']+\'\,/g)) {
    str= str.replace(/(?<!^|\:)\'[^\']+\'\,/g, "',");
}
// loop 1: // str = "'aaaaaa':'bbbbbb','cccccc':'dddddd'gggggg','eeeeee':'ffffff'"
// loop 2: // str = "'aaaaaa':'bbbbbb','cccccc':'dddddd','eeeeee':'ffffff'"
// no more matches so moving on

// return final string "'aaaaaa':'bbbbbb','cccccc':'dddddd','eeeeee':'ffffff'"
return str;

现在知道上面一系列的RegExp可以做得更优雅了,但我要找的不是droid

以上代码在最新版本的 Edge、Firefox 和 Chrome 中进行了测试,即使 JavaScript 抛出错误,它在这些浏览器中仍然可以正常工作,即使使用 lookbehind .

但正如 this page 所述,仅 76.49% 的互联网用户使用的浏览器支持 RegExp lookbehind,我对只有 3/4 访问我网站的人能够使用它的一部分不感兴趣.

所以我正在寻找上述 RegExp 的后视部分的解决方法。

我已经尝试了这里列出的所有解决方案:

基本上可以归结为

  1. 修改代码以使用先行,
  2. 捕获前面的字符以及匹配项,然后将前面的字符替换为自身
  3. 在服务器端执行

并且抛开解决方案 2(因为我不知道那个字符是什么 - 因为前面的字符可以是任何允许的字符)和解决方案 3。(因为没有服务器端参与此事务)当我尝试了建议的前瞻方法,它们都涉及更改匹配的 RegExp 即

\'[^\']+\'\:

将新格式与前瞻相匹配。但老实说,我什至不知道从哪里开始更改它以匹配前瞻模式。

这些是我要找的机器人。

给定上述 2 种后视模式:

/(?<!^|\,)\'[^\']+\'\:/g

/(?<!^|\:)\'[^\']+\'\,/g

具有前瞻功能的新模式(做同样的事情)会是什么样子?

此模式 (?<!^|\,)\'[^\']+\'\: 断言不是字符串的开头或直接在左侧的 ,。所以除了 ,

左边应该有一个字符

你可以这样写,用一个捕获组匹配你要匹配的之前的内容来替换,并用替换中的组来保留它。

请注意,您不必转义 ' :,

([^,])'[^']+':

例如

str= str.replace(/([^,])'[^']+':/g, "':");

你可以用

做同样的事情
str= str.replace(/([^:])'[^']+',/g, "',");