您可以使用这个模式:
"((?:<|\\G(?<!\\A))\\s*)(p[0-9]+)(\\s*=\\s*)(v[0-9]+)"
为确保这些对在一个开角括号之后,该模式以以下内容开头:
(?:<|\\G(?<!\\A))
这意味着:一个开角括号或者在上一次匹配的结尾
\\G
是一个锚点,用于定位在上一次匹配之后或字符串的开头(换句话说,它是正则表达式引擎在字符串中的最后位置,在字符串开始时为零)。为了避免在字符串开头进行匹配,我添加了一个负向回顾后发断言 (?<!\\A)
-> 不以字符串开头为前缀。
这个技巧强制每个成对出现的字符都要先于另一个成对或者一个<
。
例如:
String subject = "p5=v5 <p0=v0 p1=v1 p2=v2 p3=v3> p4=v4"
String pattern = "((?:<|\\G(?<!\\A))\\s*)(p[0-9]+)(\\s*=\\s*)(v[0-9]+)"
String result = subject.replaceAll(pattern, "$1$4$3$2")
如果您需要
p和
v具有相同的数字,您可以将其更改为:
String pattern = "((?:<|\\G(?<!\\A))\\s*)(p([0-9]+))(\\s*=\\s*)(v\\3)";
String result = subject.replaceAll(pattern, "$1$5$4$2");
如果尖括号之间的部分可以包含其他不成对的内容:
String pattern = "((?:<|\\G(?<!\\A))(?:[^\s>]+\\s*)*?\\s*)(p([0-9]+))(\\s*=\\s*)(v\\3)";
String result = subject.replaceAll(pattern, "$1$4$3$2");
注意:所有这些模式只检查是否有一个开角括号,但不检查是否有一个闭角括号。如果缺少一个闭角括号,则所有成对的内容将被替换,直到没有更多连续的成对内容为止,适用于前两个模式,并且适用于第三个模式的下一个闭角括号或字符串结尾。
您可以通过在每个模式的末尾添加(?=[^<>]*>)
来检查是否存在闭角括号。但是,添加此内容会使您的模式性能非常低。最好使用(?<=<)[^<>]++(?=>)
搜索角括号之间的部分,并在回调函数中执行成对替换。您可以查看this post以实现它。
<
和>
符号? - Pshemo<
和>
之间的那些对。 - user3329098<...>
中的数据。是否可能存在在其外部的x=y
对,例如<..>p4=v4
,而您希望避免这种情况? - Pshemo