REST过滤器/搜索参数的Java正则表达式模式?

REST过滤器/搜索参数的Java正则表达式模式?,java,regex,Java,Regex,我的REST API中有一个过滤器参数,它可以如下所示: owner='bob' // owner is bob owner!'bob' // owner is not bob owner.town='bel*' // owner's town starts with bel owner.town='*bel*'

我的REST API中有一个过滤器参数,它可以如下所示:

owner='bob'                            // owner is bob
owner!'bob'                            // owner is not bob
owner.town='bel*'                      // owner's town starts with bel
owner.town='*bel*'                     // owner's town contains bel
owner.car='{ some json blob here}'     // owner's car equals some json blob
owner.car~                             // owner has a property named car
所以我想捕捉:

  • 必需的字符串键
  • 可以包含字母、数字、下划线、点、连字符或冒号
  • 必需的运算符:+||~
  • 可选值,可以以可选星号开始和/或结束
  • 如果存在可选值,则必须用单引号括起来
我从以下几点开始,但它没有返回我所期望的:

String filter = "owner='bob'";
Pattern.compile("(\\w+?)(=|!|~)(*?)(\\w+?)(*?)");
final Matcher matcher = pattern.matcher(filter);

// Results
matcher.group(1)   // "owner"
matcher.group(2)   // "="
matcher.group(3)   // "\"
matcher.group(4)   // ""
matcher.group(5)   // "bob"
matcher.group(6)   // ""
matcher.group(7)   // "\"

我遇到的问题:

  • 我不认为
    (*?)
    正确地捕获了零个或一个星号
  • 在调用
    matcher.group(任何内容)

我很确定我还没有发现正则表达式存在其他问题…

我将使用以下正则表达式:

^([\w.:-]+)([=!~])('.*')?$
它由三个连续的组组成,定义如下:

  • 第一组匹配键,键是由字母、数字、下划线、点、连字符或冒号组成的非空序列
  • 第二组与运算符匹配,它是“=”、“!”或“~”中的一个
  • 第三个可选组与其余组匹配,当运算符不是“~”时,该组将是属性值
你可以


请注意,如果提到值可以以
*
开头或结尾,则意味着它不能在其他位置包含
*
,则您需要将第三组更改为
('\*?[^*]*\*?')

你熟悉像或这样的正则表达式测试站点吗?它们应该能帮助你找出这些类型的问题。@Rory我已经编辑了我的答案,把它们考虑进去了。只需将它们列在字符类中(知道
\w
包括字母、数字和下划线),并确保将
-
放在前面或最后,这样就不会将其解释为range@Rory在您的正则表达式中,
[a-zA-Z0-9\\\-\\\:]+
匹配任何字母、数字、下划线、破折号、点,一次或多次使用空格或冒号。该部分可以简化为
[\w.:-]+
\w
包含字母、数字和下划线,点不需要在字符类中转义,
-
如果是第一个或最后一个,也不需要转义)。使用
^…$
确保匹配整个字符串或不匹配,并且
(?!\\s*$)
确保匹配的整个字符串不仅仅是空格。当然,请参阅建议的
('\*?[^*]*\*?')
备选方案?这是一个引号,后跟一个可选星号,后跟任意数量的非星号字符,后跟一个可选星号,后跟结束引号。只需将两个星号放在各自的捕获组中,您可能更喜欢将组本身设置为可选的,而不是字符:
(\*)?
(注意:在Java中,您需要将我正在编写的每个
\
翻一番)@Rory查看您的示例*应该位于“…”内,而不是外部,因此更像是
”(\*)?(*))(\\*)?“
也许?
([\w.:-]+)([=!~)(?:”(\*?)([^']+)(\*?))?
应该可以