使用JavaScript正则能否将seq行内容复制到后续所有val开头行
结论
不用写for循环逐行处理。只要你用的正则引擎支持可变长度断言,单次全局替换就能实现效果;就算是不支持可变长度断言的老旧正则引擎,也只需要重复执行你现在写的替换规则直到没有匹配项就行,不需要手写循环逻辑。
原有写法的问题
你当前用的正则(^seq.*$)(\n)(val)只会匹配seq行后面紧挨着的第一个val行,没覆盖同组里后面的其他val行,自然没法给所有val行加上前缀。
具体实现方案
首先要开两个正则基础开关:
- 多行模式(一般标记为
m):让^、$匹配每一行的开头和结尾,不是整个文本的首尾 - 全局匹配(一般标记为
g):替换所有符合规则的内容,不是只换第一个
支持可变长度反向断言的引擎(.NET、ES2018及以上版本JavaScript、Java9+、Python第三方regex模块等)
这类引擎可以直接单次替换完成,查找规则写:
(?m)(?<=^(seq.*)$(?:\r?\n(?!seq ).*)*\r?\n)^(val.*)$
替换规则写:
$1 $2
这个正则的逻辑是:对每一个val开头的行,往回找最近的、中间没有其他seq开头行的seq行内容,把这个seq内容拼到当前val行前面就完成了。
不支持可变长度反向断言的引擎(Python标准库re、老版本Java、部分老旧文本编辑器)
不用写循环逐行处理,直接反复执行你原来的替换规则就行:
- 查找:
(^seq.*$)(\n)(val) - 替换:
$1$2$1 $3
每次替换都会给紧接在seq开头行(包括已经拼上seq前缀的val行)后面的val行加前缀,比如第一次替换完第一个val加了前缀,第二次替换时,加了前缀的那行本身开头就是seq,它后面的第二个val就会被匹配加上前缀,多执行几次直到没有匹配结果,就能得到你要的最终效果。对你给的样例来说,执行3次替换就能完全处理完所有val行。
内容的提问来源于stack exchange,提问作者straj
相关产品推荐
相关产品推荐

