我正在编写一个消息格式化解析器,它具有解析链接的能力(以及其他)。此特定情况需要解析<url|linkname>
中的链接,并仅使用linkname
替换该文本。这里的问题是,url
或linkname
可能包含\1
或\2
个字符,但在任何顺序中都可以包含linkname
或([^\n+])
个字符(尽管最多只有一个)。我想匹配模式,但保持&#34;无效&#34;字符。此问题解决了url
,因为该模式的一部分只是[\1\2]
,但.replace(/\1|\2/g, "")
片段与更复杂的模式相匹配,更具体地来说是{[\1\2]{0,2}
的URL验证模式3}}。手动修改整个模式以容忍\1\2
到处都是不容易的,我需要这种模式来保留这些字符,因为它们用于跟踪目的(所以我不能只是{{1}匹配前)。
如果无法进行此类匹配,是否有一些自动方式可靠地修改RegExp以在每个字符匹配之间添加[chars]
,将url
添加到所有is.js
匹配等
这是取自/(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?/i
的{{1}}模式:
<url|linkname>
此模式已根据我的目的和let namedUrlRegex = /<((?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?)\|([^\n]+)>/ig;
格式进行了调整,如下所示:
...
使用它的代码在这里:is.js
澄清示例(namedUrlRegex
表示上面的$2
变量,linkname
是捕获Current behavior:
"<googl\1e.com|Google>".replace(..., "$2") // "<googl\1e.com|Google>" WRONG
"<google.com|Goo\1gle>".replace(..., "$2") // "Goo\1gle" CORRECT
"<not_\1a_url|Google>".replace(..., "$2") // "<not_\1a_url|Google>" CORRECT
Expected behavior:
"<googl\1e.com|Google>".replace(..., "$2") // "Google" (note there is no \1)
"<google.com|Goo\1gle>".replace(..., "$2") // "Goo\1gle"
"<not_\1a_url|Google>".replace(..., "$2") // "<not_\1a_url|Google>"
的捕获组:
\1
请注意,
\2
的相同规则适用于\1\2
,\1...\2
,\2...\1
,\1
等上下文:用于将WYSIWYG编辑器中的字符串规范化为它将显示的长度/内容,保留当前选择的位置(由
\2
和<url|linkname>
表示,以便它解析后可以恢复)。如果&#34;插入&#34;完全删除(例如,如果光标在链接的URL中),它将选择整个字符串。除了选择在url片段中开始或结束时,一切都按预期工作。编辑以澄清:我仅想要更改字符串中的细分如果它遵循
url
格式\1
匹配的网址格式(容忍\2
,linkname
)和\n
由非<...|...>
个字符组成。如果在not_a_url
字符串中未满足此条件,则应按照上面的{{1}}示例将其保留为未更改。
答案 0 :(得分:0)
我最终制作了一个符合所有&#34;符号的RegEx&#34;在表达中。其中一个怪癖是,它希望转义=
,!
,(?:...)
个字符,即使在(?=...)
,(?!...)
,{{1}之外也是如此表达。这可以通过在处理之前转义它们来解决。
let r = /(\\.|\[.+?\]|\w|[^\\\/\[\]\^\$\(\)\?\*\+\{\}\|\+\:\=\!]|(\{.+?\}))(?:((?:\{.+?\}|\+|\*)\??)|\??)/g;
let url = /((?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?)/
function tolerate(regex, insert) {
let first = true;
// convert to string
return regex.toString().replace(/\/(.+)\//, "$1").
// escape :=!
replace(/((?:^|[^\\])\\(?:\\)*\(\?|[^?])([:=!]+)/g, (m, g1, g2) => g1 + (g2.split("").join("\\"))).
// substitute string
replace(r, function(m, g1, g2, g3, g4) {
// g2 = {...} multiplier (to prevent matching digits as symbols)
if (g2) return m;
// g3 = multiplier after symbol (must wrap in parenthesis to preserve behavior)
if (g3) return "(?:" + insert + g1 + ")" + g3;
// prevent matching tolerated characters at beginning, remove to change this behavior
if (first) {
first = false;
return m;
}
// insert the insert
return insert + m;
}
);
}
alert(tolerate(url, "\1?\2?"));