2021-12-10 04:28:55
使用正则表达式有条件地向特定行添加文本的核心方法是通过负向先行断言(Negative Lookahead)结合行锚点与捕获组,确保仅在目标行不包含指定词汇时追加内容,同时精确匹配单行范围。
具体实现步骤识别目标行并捕获内容
使用正则表达式 (s*schemas:.*) 匹配以 schemas: 开头的行,并捕获整行内容。
s*:匹配行首零个或多个空白字符(处理缩进)。
schemas::匹配字面字符串。
.*:匹配 schemas: 后到行尾的所有字符。
(...):捕获组,存储匹配的整行内容供后续替换使用。
条件判断:排除包含指定词汇的行
通过负向先行断言 ^(?!.*(?:foos*$|foo,)) 确保当前行不包含独立项 foo。
^ 和 $:行锚点,限定匹配范围为单行。
(?!...):负向先行断言,断言后续内容不匹配括号内模式。
.*:匹配任意字符(零个或多个)。
(?:foos*$|foo,):非捕获组,匹配两种情况之一:
foos*$:foo 后跟零个或多个空白字符且为行尾(如 schemas: bar,foo)。
foo,:foo 后跟逗号(如 schemas: foo,bar)。
替换操作
替换字符串为 $1,foo,其中 $1 引用捕获的原始行内容,并在行尾追加 ,foo。
Java 中需使用 Pattern.MULTILINE 标志,使 ^ 和 $ 匹配每一行的开头和结尾,而非整个字符串。
负向先行断言需排除 food、fool 等包含 foo 的词,仅匹配独立项 foo(如 foo, 或行尾 foo)。
负向先行断言可能增加资源消耗,对于大文件可考虑先字符串查找再正则替换。
Java 不支持可变长度模式的负向后行断言(如 .*),因此负向先行断言更灵活。
通过结合行锚点、捕获组和负向先行断言,正则表达式能够高效解决有条件修改文本行的需求,适用于多种自动化处理场景。