我正在编写一个消息格式化解析器,它能够(除其他外)解析链接。这种特定情况需要解析 from of 中的链接<url|linkname>
并将该文本替换为linkname
. 这里的问题是,两者url
或linkname
可能或可能不包含或以任何顺序在任何地方包含\1
或字符(尽管每个最多一个)。\2
我想匹配模式但保留“无效”字符。这个问题自己解决了,linkname
因为模式的那部分是 just ([^\n+])
,但是url
片段匹配一个更复杂的模式,更具体地说是来自is.js的 URL 验证模式。手动修改整个模式以容忍它并非易事[\1\2]
到处都是,我需要模式来保留这些字符,因为它们用于跟踪目的(所以我不能只是.replace(/\1|\2/g, "")
在匹配之前)。
如果这种匹配是不可能的,是否有一些自动化的方法可以可靠地修改正则表达式以[\1\2]{0,2}
在每个字符匹配之间添加、添加\1\2
到所有[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
此模式适用于我的目的,<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;
使用它的代码在这里:JSFiddle
澄清示例(...
代表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
相同规则上下文:这用于将来自 WYSIWYG 编辑器的字符串规范化为它将显示的长度/内容,保留当前选择的位置(由 表示
\1
,\2
因此可以在解析后恢复)。如果“插入符号”被完全删除(例如,如果光标位于链接的 URL 中),它将选择整个字符串。一切都按预期工作,除了选择在 url 片段中开始或结束时。编辑澄清:我只想更改字符串中的段,如果它遵循
<url|linkname>
whereurl
匹配 URL 模式(容忍\1
,\2
)的格式并且linkname
由非\n
字符组成。如果字符串中不满足此条件<...|...>
,则应按照上面的示例保持不变。not_a_url