regex - 如果在字符串 A 之前的任何位置找到字符串 B,则尝试匹配字符串 A
问题描述
我想要做的是,如果一个字符串由一些以“!”开头的子字符串组成 封装在 "[" 和 "]" 中,通过空格将这些括号与字符串的其余部分分开,例如 "[!foo]" --> "[ !foo ]", "[!bar]" --> "[ !bar ]" 等。由于该子字符串可以是可变长度的,我认为这必须使用正则表达式来完成。我的想法是分两步来做——首先分开第一个括号,然后分开第二个括号。
第一个并不难;正则表达式是公正的\[!
,所以我可以str = str.replace(/\[!/g, "[ !");
用 Javascript 来做。这是我无法上班的第二部分。
因为现在,如果字符串文字“[!”,我需要匹配“]” 在它之前的任何地方都可以找到。所以一个简单的正向向后看是不匹配的,因为它只直接看后面:(?<=\Q[ !\E)\]
不匹配。
而且我仍然不明白为什么,但是我不允许正面向后看非固定长度;在控制台中(?<=\Q[ !\E.*)\]
抛出错误,并且此正则表达式调试器产生一个模式错误,解释“后视中的量词使其宽度不固定”。Syntax Error: Invalid regular expression: missing /
在后视和捕获组之间放置一个非固定宽度的非捕获组不起作用;(?<=\Q[ !\E)(?:.*)\]
不匹配。
一件行不通的事情就是试图匹配“[!” 在字符串的开头,因为整个 "[!foo]" 字符串实际上本身就是一个更大字符串的子字符串,并且不在开头。
我错过了什么?
解决方案
使用 2 个正向环视,您可以断言左侧是一个左方括号(?<=\[)
然后匹配任何字符,除了]
使用前面带有感叹号的否定字符类 ![^[\]]+
,并断言右边是一个右方括号,使用(?=])
请注意,在 Javascript 中,lookbehind 尚未得到广泛支持。
(?<=\[)![^[\]]+(?=])
在替换中使用匹配的子字符串$&
[
"[!foo]",
"[!bar]"
].forEach(s =>
console.log(s.replace(/(?<=\[)![^[\]]+(?=])/g, " $& "))
)
或者您也可以使用 3 个捕获组:
(\[)(![^\]]+)(\])
在更换使用
$1 $2 $3
[
"[!foo]",
"[!bar]"
].forEach(s =>
console.log(s.replace(/(\[)(![^\]]+)(\])/g, "$1 $2 $3"))
)
推荐阅读
- linux - 如何释放eventfd/eventpoll/timerfd创建的匿名inode?
- r - 使用 lapply 或在 R 中的用户定义函数中的非标准评估
- docker - 如何通过在 localhost 的 Docker-Kubernetes 上运行的服务访问 Kubernetes Pod
- python-3.x - 根据不同的文件使用不同的参数?
- visual-studio - 构建时如何禁用 NuGet 运行
- c++ - 即使没有析构函数,非静态类成员也会被销毁吗?
- html - 如何将内容添加到特定的网格列?
- javascript - 使用从 MVC 中的 ajax 返回的 HTML Grid 中的数据
- java - 从 odnoklassniki 获取流媒体链接会导致 400 Bad request
- android - androidX jetifier - 有没有办法忽略喷射.JAR?