Java 正则表达式,匹配特定XML标记的内容,但不匹配标记本身

Java 正则表达式,匹配特定XML标记的内容,但不匹配标记本身,java,regex,Java,Regex,我整天都在用我的头撞击这个正则表达式 任务看起来很简单,我有许多XML标记名,必须替换(屏蔽)它们的内容 比如说 <Exony_Credit_Card_ID>242394798</Exony_Credit_Card_ID> 242394798 必须成为 <Exony_Credit_Card_ID>filtered</Exony_Credit_Card_ID> 过滤 有多个具有不同名称的此类标记 如何匹配内部的任何文本,但不匹配标记本身 编辑

我整天都在用我的头撞击这个正则表达式

任务看起来很简单,我有许多XML标记名,必须替换(屏蔽)它们的内容

比如说

<Exony_Credit_Card_ID>242394798</Exony_Credit_Card_ID>
242394798
必须成为

<Exony_Credit_Card_ID>filtered</Exony_Credit_Card_ID>
过滤
有多个具有不同名称的此类标记

如何匹配内部的任何文本,但不匹配标记本身

编辑:我应该再次澄清。在我的情况下,分组然后使用组来避免替换其中的文本是行不通的,因为当我将其他标记添加到表达式中时,后续匹配的组号是不同的。例如:

"(<Exony_Credit_Card_ID>).+(</Exony_Credit_Card_ID>)|(<Billing_Postcode>).+(</Billing_Postcode>)"
“()。+()|()。+()”

replaceAll使用字符串
“$1filtered$2”
不起作用,因为当正则表达式匹配帐单邮政编码时,它的组是3和4,而不是1和2

我没有调试此代码,但您应该使用类似的内容:

Pattern p = Pattern.compile("<\\w+>([^<]*)<\\w+>");
Matcher m = p.matcher(str);
if (m.find()) {
    String tagContent = m.group(1);
}
Pattern p=Pattern.compile(“([^
stringresultstring=subjectString.replaceAll(
“(?x)#(多行正则表达式):匹配…\n”+
“#其中一个开始标记\n”+
“[^]*#匹配其中包含的内容\n”+
“#匹配相应的结束标记”,
“过滤”);

在您的情况下,我会使用以下方法:

(?<=<(Exony_Credit_Card_ID|tag1|tag2)>)(\\d+)(?=</(Exony_Credit_Card_ID|tag1|tag2)>)

(?我会用这样的方法:

private static final Pattern PAT = Pattern.compile("<(\\w+)>(.*?)</\\1>");

private static String replace(String s, Set<String> toReplace) {
    Matcher m = PAT.matcher(s);
    if (m.matches() && toReplace.contains(m.group(1))) {
        return '<' + m.group(1) + '>' + "filtered" + "</" + m.group(1) + '>';
    }
    return s;
}
private静态最终模式PAT=Pattern.compile((*?);
专用静态字符串替换(字符串s,设置为替换){
匹配器m=匹配器;
if(m.matches()&&toReplace.contains(m.group(1))){

返回“+”过滤“+”我知道您说过,在您的情况下,依靠组号是不行的……但我真的不明白怎么做。您能不能不使用这样的东西:

xmlString.replaceAll("<(Exony_Credit_Card_ID|tag2|tag3)>([^<]+)</(\\1)>", "<$1>filtered</$1>");

xmlString.replaceAll(“([^您不能简单地使用XML解析器吗?不,文本是XML和其他文本的混合体,它是一个日志文件小心正则表达式方法的陷阱:我建议您首先检查您发布的代码段:您的代码段甚至没有编译。抱歉,我现在没有IDE。我在家。感谢您修复我的代码。据我所知,您添加了缺少的反斜杠。以及c将反勾号挂在双引号中。当然,不客气。@Tim,您所有的内联注释不都需要以换行符结尾吗?(现在无法自己测试…)@巴特:可能是的;我手动包装了第一行,但忘记添加
\n
。顺便问一下,在方法调用的两个参数之间使用换行符合法吗(我在搜索和替换术语之间添加了一个换行符)?@Tim,是的,这是完全合法的:你可以添加任意数量的标签。问题是我有多个标签,就像我说的,名称不同。当我将它们添加到一个表达式中时,过滤只对第一个组有效。我已经尝试过了。你需要将标签添加到正则表达式的第二行,并用
正如我在那里展示的那样。OP写道,有多个这样的标签具有不同的名称。@Tim Pietzcker好的,我错过了。谢谢mdrg,您的解决方案看起来很有希望,因为它不依赖组号?或者我认为是这样。非捕获组内的所有内容都不匹配吗?@avok00是的,它不需要组号。您可以用使用模糊字符串
进行过滤
,因为标记不是匹配的一部分。这是通过如上所述的零宽度前向和后向查找完成的。
xmlString.replaceAll("<(Exony_Credit_Card_ID|tag2|tag3)>([^<]+)</(\\1)>", "<$1>filtered</$1>");
"<(Exony_Credit_Card_ID|tag2|tag3)>" + // matches the tag itself
"([^<]+)" + // then anything in between the opening and closing of the tag
"</(\\1)>" // and finally the end tag corresponding to what we matched as the first group (Exony_Credit_Card_ID, tag1 or tag2)

"<$1>" + // Replace using the first captured group (tag name)
"filtered" + // the "filtered" text
"</$1>" // and the closing tag corresponding to the first captured group