Java正则表达式告诉我们哪一列不匹配。

3

您好,

我的Java代码如下:

Pattern p = Pattern.compile("^[a-zA-Z0-9$&+,:;=\\[\\]{}?@#|\\\\'<>._^*()%!/~\"`  -]*$");
String i = "f698fec0-dd89-11e8-b06b-☺";
Matcher tagmatch = p.matcher(i);
System.out.println("tagmatch is " + tagmatch.find());

如预期的那样,答案将是错误的,因为其中包含了一个“☺”字符。然而,我想显示不匹配的列号。对于这个例子来说,应该显示第25列有无效字符。
请问我该如何做到这一点?
1个回答

4

你应该从你的正则表达式中移除锚点,然后使用 Matcher#end() 方法来获取上一个匹配停止的位置,像这样:

String i = "f698fec0-dd89-11e8-b06b-☺";
Pattern p = Pattern.compile("[\\w$&+,:;=\\[\\]{}?@#|\\\\'<>.^*()%!/~\"`  -]+");
Matcher m = p.matcher(i);
if (m.lookingAt() && i.length() > m.end()) { 
   System.out.println("Match <" + m.group() + "> failed at: " + m.end());
}

输出:

Match <f698fec0-dd89-11e8-b06b-> failed at: 24

PS: 我已经使用了 lookingAt() 来确保我们匹配从区域开头开始的模式。您也可以使用 find() 来获取下一个匹配项,或者将起始锚定点保留在模式中。

"^[\\w$&+,:;=\\[\\]{}?@#|\\\\'<>.^*()%!/~\"`  -]+"

使用find()方法,使其像上面的代码一样有效地运行,可以达到预期效果。

阅读lookingAt()find()之间的区别

我已经重构了你的正则表达式,使用\w代替[a-zA-Z0-9_],并使用量词+(表示匹配1个或多个)而不是*(表示匹配0个或多个),以避免返回零长度匹配的成功结果。


1
或者只保留起始锚点。 - shmosel
1
请注意,lookingAt()/find()将始终返回true,因为*匹配零长度字符串。您需要比较end()i.length()来检查它是否是完全匹配。 - shmosel
你的代码没有打印出是否匹配了预期的模式。如果开头有一个意外的字符,就不会输出任何内容。否则,它会打印一些东西,但我不知道整个字符串是否匹配。 - モキャデ
如果在正则表达式中包含$符号,则find()/lookingAt()方法会失败,随后您将无法使用end()方法,因为调用该方法将引发异常:java.lang.IllegalStateException: No match available - anubhava
1
只有在您认为部分匹配是成功的情况下,才会出现OP的意图。请参阅我的先前评论。 - shmosel
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接