【问题标题】:Regular Expression to find words separated with space, backtracking正则表达式查找用空格分隔的单词,回溯
【发布时间】:2016-01-17 19:50:24
【问题描述】:

我必须找到以空格分隔的单词。使用最小回溯的最佳做法是什么?

我找到了这个解决方案:

Regex: \d+\s([a-zA-Z]+\\s{0,1}){1,} in a sentence
Input: 1234 this is words in a sentence

所以,this is words - 我必须使用正则表达式([a-zA-Z]+\\s{0,1}){1,} 和单词in a sentence 进行检查,我必须使用正则表达式in a sentences 中的常量单词进行检查。

但在这种情况下,regex101.com 给了我 4156 步的调试,这是灾难性回溯。有什么办法可以避免吗?

我还有其他更复杂的示例,它需要 86000 步并且无法验证。

主要问题,我必须找到所有由空格分隔的单词,但同时正则表达式包含由空格分隔的单词(常量)。这就是我有灾难性回溯的地方。

我必须使用 Java 来做到这一点。

【问题讨论】:

  • 您可以将[a-zA-Z] 替换为\w 来表示所有非空白字符,不是吗?
  • 我不知道我是否误解了你的问题,但你不能简单地使用String.split()吗?
  • 如果您根据空格/点/空白分割字符串并从那里开始会有帮助吗?
  • 尝试使用所有格量词和[a-zA-Z]++
  • 这个表达式"\\d+\s[a-zA-Z\\s]+ in a sentence"matches in 34 steps。不幸的是,它允许连续有多个空格。

标签: java regex backtracking


【解决方案1】:

你想找到以space分隔的单词。所以你至少应该说1 or more space。你可以用它来代替,它只需要37个步骤。

\d+\s([a-zA-Z]+\s+)+in a sentence

查看演示。

https://regex101.com/r/tD0dU9/4

对于java双重转义,即\d==\\d

【讨论】:

  • 这是一个很好的解决方案。我有一个正则表达式和输入字符串的生成器,现在,使用你的优化我得到了更多的性能。我现在要测试,可能我还有其他问题。谢谢!我稍后会标记。
【解决方案2】:

您可以尝试将字符串拆分为字符串数组,然后在消除数组中与您对单词的定义不匹配的任何成员(例如空格或标点符号)后找到数组的大小

String[] mySplitString = myOriginalString.split(" ");
for(int x = 0; x < mySplitString.length; x++){
    if(mySplitString[x].matches("\\w.*"/*Your regex for a word here*/)) words++;
}

mySplitString 是从原始字符串中拆分出来的字符串数组。删除所有空白字符,并将位于空白之前、之后或中间的子字符串放入新的字符串数组中。 for 循环遍历拆分的 String 数组并检查以确保每个数组成员都包含一个单词(字符或数字至少一次)并将其添加到总字数中。

【讨论】:

    【解决方案3】:

    如果我理解正确,你想匹配任何以空格分隔的单词加上“在一个句子中”这个句子。

    您可以尝试以下解决方案:

    (in a sentence)|(\S+)
    

    正如在 regex101 上的这个例子中看到的:Exemple

    正则表达式匹配 61 步。 在“in a sentence”句子之后,您可能会遇到标点符号问题。做一些测试。

    希望我对你有所帮助。

    【讨论】:

    • @vks 的解决方案需要 37 个步骤
    猜你喜欢
    • 2015-09-10
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    • 2021-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多