旧浏览器中不支持的lookbehind的解决方法?

Posted

技术标签:

【中文标题】旧浏览器中不支持的lookbehind的解决方法?【英文标题】:Workaround for unsupported lookbehind in older browsers? 【发布时间】:2021-08-02 01:04:19 【问题描述】:

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

我有这 2 种模式,其中包括后视:

    匹配模式'(anything not a ')':(即'abcdef':),如果它不在字符串的开头或前面没有强>

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

    匹配模式 '(anything not a ')',(即 'abcdef',)如果它不在字符串的开头或前面没有 强>

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

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

带有后视功能的完整代码:

我有一个用户输入,然后我通过一系列.replace() 运行,每个输入都有一个正则表达式,以使其匹配某种格式。

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 可以做得更优雅,但那些不是我要找的机器人。

上述代码已在最新版本的 Edge、Firefox 和 Chrome 中进行了测试,即使 javascript 抛出错误,它在这些浏览器中仍然可以正常工作,即使是在后面看。

但正如this page 所说,RegExp 后视仅由 76.49% 的互联网使用的浏览器支持,我对访问我网站的只有 3/4 的人能够使用其中的一部分不感兴趣。

所以我正在为上述 RegExp 的后向部分寻找一种解决方法。

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

This Question This Question This Question

基本上都归结为任一

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

当我尝试时,将解决方案 2(因为我不知道该字符是什么 - 因为前面的字符可以是任何允许的字符)和解决方案 3(因为此事务不涉及服务器端)放在一边建议的前瞻方法,它们都涉及更改匹配的 RegExp 即。

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

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

这些是我正在寻找的机器人。

鉴于上述 2 种模式与后向:

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

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

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

【问题讨论】:

【参考方案1】:

此模式(?&lt;!^|\,)\'[^\']+\'\: 断言不是字符串的开头,也不是直接在左侧的,。所以除了,之外,左边应该有一个char

您可以使用捕获组来匹配您要匹配替换的内容之前的内容,并使用替换中的组来保留它。

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

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

例如

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

你也可以这样做

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

【讨论】:

以上是关于旧浏览器中不支持的lookbehind的解决方法?的主要内容,如果未能解决你的问题,请参考以下文章

JS Regex lookbehind 在 firefox 和 safari 中不起作用

非固定长度的lookbehind解决方法

没有LookBehind功能的正则表达式

来自程序集的类型是使用旧版本的 blend sdk 构建的,并且在 Windows Presentation Foundation 4 项目中不受支持

正则表达式的可变长度lookbehind-assertion替代方案

php系统中不支持mysql数据库的解决方法