正则表达式挂起-Java匹配器

正则表达式挂起-Java匹配器,java,regex,string,Java,Regex,String,字符串: 水、月桂醇硫酸钠、十二烷基硫酸钠、二甲基硅油、椰酰胺MEA、碳酸锌、二硬脂酸乙二醇酯、氯化钠、硫锌、二甲苯磺酸钠、十六醇、香料、瓜尔豆羟丙基三氯化铵、硫酸镁、苯甲酸钠、月桂醇硫酸铵、碳酸镁氢氧化物、芳樟醇、,丁基苯基甲基丙醛、柠檬烯、羟基异己基3-环己烯醛、苯甲醇、己基肉桂醛、香茅醇、生育酚醋酸酯、石蜡液体、多萘磺酸钠、CI 19140、DMDM海因、CI 15510、甲基氯异噻唑啉酮、EDTA二钠、EDTA四钠、甲基异噻唑啉酮 当前正则表达式: System.out.println(

字符串:

水、月桂醇硫酸钠、十二烷基硫酸钠、二甲基硅油、椰酰胺MEA、碳酸锌、二硬脂酸乙二醇酯、氯化钠、硫锌、二甲苯磺酸钠、十六醇、香料、瓜尔豆羟丙基三氯化铵、硫酸镁、苯甲酸钠、月桂醇硫酸铵、碳酸镁氢氧化物、芳樟醇、,丁基苯基甲基丙醛、柠檬烯、羟基异己基3-环己烯醛、苯甲醇、己基肉桂醛、香茅醇、生育酚醋酸酯、石蜡液体、多萘磺酸钠、CI 19140、DMDM海因、CI 15510、甲基氯异噻唑啉酮、EDTA二钠、EDTA四钠、甲基异噻唑啉酮

当前正则表达式:

System.out.println(string.matches("([\\W]*\\b[A-Z\\d]\\w+\\b[\\W]*)+"));
Java应用程序挂起。我在正则表达式中找不到错误。通过谷歌搜索,我发现这可以被称为“灾难性回溯”!? 如果正则表达式只包含大写单词,则它应该与字符串匹配
例如,如果1个单词是小写,则不应与之匹配。

也许您想到的是

String regex = "([A-Z][\\d\\w]+( [A-Z][-\\d\\w]+)*, )*[A-Z][-\\d\\w]+( [A-Z][-\\d\\w]+)*\\.";
System.out.println(string.matches(regex));
返回true

正则表达式的问题在于它过于复杂。在获得
true
之前添加表达式的缺点是,它可以匹配您没有想到的内容

Random rand = new Random();
while(true) {
    byte[] bytes = new byte[40];
    rand.nextBytes(bytes);
    for (int i = 0; i < bytes.length; i++) bytes[i] &= 0x7F;
    String string = new String(bytes, 0);
    if (string.matches("([\\W]*\\b[A-Z\\d]\\w+\\b[\\W\\d]*)+"))
        System.out.println(string);
}

也许你想的是

String regex = "([A-Z][\\d\\w]+( [A-Z][-\\d\\w]+)*, )*[A-Z][-\\d\\w]+( [A-Z][-\\d\\w]+)*\\.";
System.out.println(string.matches(regex));
返回true

正则表达式的问题在于它过于复杂。在获得
true
之前添加表达式的缺点是,它可以匹配您没有想到的内容

Random rand = new Random();
while(true) {
    byte[] bytes = new byte[40];
    rand.nextBytes(bytes);
    for (int i = 0; i < bytes.length; i++) bytes[i] &= 0x7F;
    String string = new String(bytes, 0);
    if (string.matches("([\\W]*\\b[A-Z\\d]\\w+\\b[\\W\\d]*)+"))
        System.out.println(string);
}

我建议您按单词分割输入字符串,然后进行模式匹配,事件更简单:如果您只想测试每个单词的第一个字母是否为大写,则不进行模式匹配,如:

for (String s : string.split("\\W")) {
  if (s.charAt(0) < 'A' || s.charAt(0) > 'Z') {
    return false;
  }
}
for(字符串s:String.split(\\W”)){
如果(s.charAt(0)<'A'| | s.charAt(0)>'Z'){
返回false;
}
}

对我来说,听起来快多了(如果需要的话,你甚至可以使用失败的单词)。

我建议你将输入字符串按单词分割,然后进行模式匹配,事件更简单:如果你只想测试每个单词的第一个字母是否为大写,不要进行模式匹配,如:

for (String s : string.split("\\W")) {
  if (s.charAt(0) < 'A' || s.charAt(0) > 'Z') {
    return false;
  }
}
for(字符串s:String.split(\\W”)){
如果(s.charAt(0)<'A'| | s.charAt(0)>'Z'){
返回false;
}
}


对我来说,听起来快多了(如果需要,你甚至可以使用失败的单词)。

你的预期输出是什么?简化输入时会发生什么情况?如果源中的所有单词都以大写字符开头,则为true。如果有小写字符,则为False。我认为字符串中的“3-”是原因。我仍然不明白为什么会出现这种情况,不定式计算。你的预期输出是什么?简化输入时会发生什么情况?如果源中的所有单词都以大写字符开头,则为true。如果有小写字符,则为False。我认为字符串中的“3-”是原因。我仍然不明白为什么这种情况下,不定式计算。返回false。你能解释一下这个方法吗?我用这个正则表达式:string.matches(([\\W]*\\b[a-Z\\d]\\W+\\b[\\W\\d]*)+)得到了它。似乎当一个单词后面的数字出现时,它就不再起作用了。所以我添加了“\d”。有人能解释为什么这会导致线程的“挂起/无限评估”吗?@user1635689在不使用
羟基异己基3-环己烯甲醛的情况下尝试一下。您的正则表达式与一个字符的单词不匹配,
-
不是单词字符。如果它在没有该字符串的情况下工作,可能正则表达式
“([\\W]*\\b[A-Z\\d]\\W*\\b[\\W]*)+”
会起作用。
-
位于示例字符串的“字”中。我不知道有哪种化学品的名字只有一个字母我知道是“羟基异己基3-环己烯碳酸酯”引起的。但我还是不知道为什么会被绞死?!返回false。你能解释一下这个方法吗?我用这个正则表达式:string.matches(([\\W]*\\b[a-Z\\d]\\W+\\b[\\W\\d]*)+)得到了它。似乎当一个单词后面的数字出现时,它就不再起作用了。所以我添加了“\d”。有人能解释为什么这会导致线程的“挂起/无限评估”吗?@user1635689在不使用
羟基异己基3-环己烯甲醛的情况下尝试一下。您的正则表达式与一个字符的单词不匹配,
-
不是单词字符。如果它在没有该字符串的情况下工作,可能正则表达式
“([\\W]*\\b[A-Z\\d]\\W*\\b[\\W]*)+”
会起作用。
-
位于示例字符串的“字”中。我不知道有哪种化学品的名字只有一个字母我知道是“羟基异己基3-环己烯碳酸酯”引起的。但我还是不知道为什么会被绞死?!它肯定比永恒更快:)谢谢,我们使用hibernate验证引擎。添加自定义验证将是一项巨大的工作,我使用这个regex:string.matches(“([\\W]*\\b[a-Z\\d]\\W+\\b[\\W\\d]*)+”)似乎当一个单词后面的数字出现时,它就不再工作了。所以我添加了“\d”。知道这导致线程“挂起/不定式求值”的原因吗?@user1635689:您有嵌套的量词(
(…[\\W\\d]*)+
)。这些通常会导致正则表达式引擎在声明失败之前需要检查的置换数呈指数级增长。您建议正则表达式是什么:1)查看上面的源字符串=预期为真,2)测试,测试,测试=预期为真3)测试,测试,测试预期为假4)N/A预期为真它肯定比永恒更快:)谢谢,我们使用hibernate验证引擎。添加自定义验证将是一项巨大的工作,我使用这个regex:string.matches(“([\\W]*\\b[a-Z\\d]\\W+\\b[\\W\\d]*)+”)似乎当一个单词后面的数字出现时,它就不再工作了。所以我添加了“\d”。知道这导致线程“挂起/不定式求值”的原因吗?@user1635689:您有嵌套的量词(
(…[\\W\\d]*)+
)。这些通常会导致permu的数量呈指数级增长