用于解析字符串的正则表达式问题

时间:2016-03-05 10:13:07

标签: java regex

我试图使用this链接生成要在Java中使用的正则表达式。

我可以使用以下类型的字符串。

1. customer calls <function_name> using <verb> on <uri> with <object>
2. customer calls <function_name> using 'POST' on <uri> with <object>
3. customer calls 'create' using 'POST' on <uri> with <object>
4. customer calls 'create' using 'POST' on <uri>

如您所见,with之后的最后一部分在我的情况下是可选的。

我实现了以下正则表达式。

.+call[s]?.+(\'\w+\'|<\w+>).+using.+(\'\w+\'|<\w+>).+on.+(\'\w+\'|<\w+>).*(with.+(\'\w+\'|<\w+>))?

但是当我给出字符串3时,我得到的输出为'create','POST',<object>, null, null而不是'create','POST',<uri>, <object>。 当我给出字符串4时,输出为'create','POST',<uri>, null, null而不是'create','POST',<uri>

没有(with.+(\'\w+\'|<\w+>))?的正则表达式适用于字符串4。 如何更改最后一部分,我需要从with可选的部分进行部分?

2 个答案:

答案 0 :(得分:1)

使用[ ]+代替.+空格

试试这个:

.+call(?:s)?.+(\'\w+\'|<\w+>)[ ]*using.+(\'\w+\'|<\w+>)[ ]*on[ ]*(\'\w+\'|<\w+>)[ ]*(?:with)?[ ]*(\'\w+\'|<\w+>)?

你会得到

 1. <function_name> <verb> <uri> <object>    
 2. 'create' 'POST' <uri> <object>    
 3. <function_name> 'POST' <uri> <object>    
 4. 'create' 'POST' <uri> null

在第4行中,最后一行是null,因为缺少结束标记(即<object>

答案 1 :(得分:1)

由于你过度使用贪婪的.+,你的正则表达式接受了太多而且回溯很多。请记住,每次编写.+.*时,正则表达式引擎都会匹配所有直到行尾,然后需要回溯。这既昂贵又容易出错 - 它几乎每次都会耗尽太多的文本,并且在使用这个结构时你应该非常小心。它并不像大多数人所期望的那样行事。

在您的情况下,简单的解决方案是实际准确地说明您期望的内容,并且从示例文本看起来您需要空白,所以只需使用\s+代替。你的正则表达式成为:

.+?\bcalls?\s+(\'\w+\'|<\w+>)\s+using\s+(\'\w+\'|<\w+>)\s+on\s+(\'\w+\'|<\w+>)(?:\s+with\s+(\'\w+\'|<\w+>))?

Demo

请注意,我还将第一个.+更改为惰性.+?(即使您可能只是将其从模式中移除,除非您还需要捕获整行),然后单词边界锚\b。我也改变了一个群体,因为你很可能不需要抓住它。