Java正则匹配问题:含in与notin包含场景下无法识别notin操作符
解决正则表达式中包含型操作符的匹配优先级问题
这个问题的核心是正则分支匹配的顺序优先级在搞鬼!你现在的操作符正则(in)|(notin)是先尝试匹配in,再尝试notin——当遇到namenotin时,字符串末尾的in会被先匹配到,剩下的namenot就被当成左操作数了,这显然不是你想要的结果。
修复方案:调整操作符的匹配顺序
把更长、更具体的操作符放在分支的前面,让正则优先尝试匹配它,修改后的操作符正则应该是:
String operatorExpr = "(?<operator>(notin)|(in))";
修改后的完整测试代码
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegExTest1 { public static void main (String args[] ) { String input[] = { "namein", "namenotin"}; // 关键修改:把notin放在in前面,优先匹配更长的操作符 String operatorExpr = "(?<operator>(notin)|(in))"; String conditionExpr ="(?<operand1>\\S+)"+ operatorExpr; Pattern p = Pattern.compile(conditionExpr); for(String in: input) { Matcher m = p.matcher(in); if (m.find()) { String operand1 = m.group("operand1"); String operator = m.group("operator"); System.out.println("Input: \""+in + "\" | Operand1 : \""+ operand1 + "\"" + "| Operator : \""+ operator + "\""); } } } }
为什么这样能解决问题?
正则的分支匹配规则是从左到右依次尝试,一旦某个分支匹配成功就停止后续匹配。把notin放在in前面后,当处理namenotin时,正则会先尝试匹配末尾的notin,匹配成功后就不会再去匹配更短的in了,这样左操作数就会被正确识别为name。
运行修改后的代码,就能得到你想要的预期输出啦!
内容的提问来源于stack exchange,提问作者ImGroot
相关产品推荐
相关产品推荐

