2013-03-05 94 views
5

我正在尝试改进一些代码的性能。它看起来是这样的:如何确定字符串是否不是正则表达式?

public boolean isImportant(String token) { 
    for (Pattern pattern : patterns) { 
     return pattern.matches(token).find(); 
    } 
} 

我注意到的是,许多模式似乎是简单的字符串文字,没有正则表达式构造。所以,我想简单的这些,而不是存储在一个单独的列表(importantList),做一个平等的测试进行了更昂贵的模式匹配,如如下:

public boolean isImportant(String token) { 
    if (importantList.contains(token)) return true; 

    for (Pattern pattern : patterns) { 
     return pattern.matches(token).find(); 
    }   
} 

如何编程确定一个特定的字符串不包含正则表达式结构?

编辑: 我应该补充说,答案不需要对性能敏感。 (即可以使用正则表达式)我主要关注isImportant()的性能,因为它被称为数百万次,而模式的初始化只进行一次。

+1

不会对字符串进行正则表达式来确定它是否是正则表达式,每次都比仅将每个字符串用作正则表达式更糟? – 2013-03-05 22:27:06

+3

@MikeM:这不是他要问的。 'hello'是一个完全有效的正则表达式。 – 2013-03-05 22:28:13

+0

不可能(至少不容易或不值得,除非您在纯字符串文字中找到某种模式)。一个简单的字符串文字是一个有效的正则表达式模式。 – AC1 2013-03-05 22:30:38

回答

3

这将是困难的。您可以检查是否存在任何正则表达式元字符;这应该是一个很好的近似值:

Pattern regex = Pattern.compile("[$^()\\[\\]{}.*+?\\\\]"); 
Matcher regexMatcher = regex.matcher(subjectString); 
regexIsLikely = regexMatcher.find(); 

是否值得它是另一个问题。你确定一个正则表达式的匹配比列表查找要慢吗(特别是因为在很多情况下你会做一个正则表达式匹配)?我敢打赌,保持正则表达式比赛要快得多。

+0

这是我一起去的解决方案。有趣的是,我将处理时间缩短了大约50%。 – 2013-03-08 17:35:25

4

我通常讨厌这样说的答案,但...

不要这样做。

它可能不会使代码运行得更快,实际上它甚至可能会导致程序花费更多时间。

如果您确实需要优化您的代码,那么可能会有更多有效的地方可供您使用。

+0

我打算让探查器回答优化是否有意义的问题。 – 2013-03-06 15:51:36

2

没有办法确定它,因为每个正则表达式模式都不是别的字符串。此外,还有几乎为正则表达式没有性能上的差异是时下智能,我敢肯定,如果模式和源长度相同,股权检查是第一个将要完成

+1

这取决于,但我估计Java会首先尝试更高效的DFA正则表达式,并且只有在表达式需要时才会交换到NFA(例如,如果它包含lookaround) – 2013-03-05 22:44:26

1

这是错误的

for (Pattern pattern : patterns) 

你应该创建一个大型的正则表达式来处理所有的模式;那么对于每个输入只能匹配一次。

+0

谢谢。我确实这样做了,结果发现使用一个巨型模式比匹配多个小模式要快1/3。 – 2013-03-06 15:48:12

相关问题