我想将我的产品过滤器放在我的网址中,但要匹配过滤词:
预期比赛:
filter:city:cityname-type:something-type2:something123-price:1000
filter:city:cityname-type2:something-type:something123-price:1000
filter:city:cityname-price:1000
更确切地说: string以“filter:”字开头,之后必须至少有一个过滤器。每个过滤器都是name:value
第一个过滤器(在本例中为“city”)是强制性的,其他则不是,其他人的订单也可以更改(city,type,type2 OR city,type2,type)
。预期的过滤器至少为1 - 20.
这是正在使用的正则表达式
^filter:((city:([a-z0-9]+)){1}((-type:([a-z0-9]+))|(-type2:([a-z0-9]+))|(-price:([0-9]+)))*)
如何只匹配每个使用过的过滤器一次,因为上面的正则表达式将匹配:
filter:city:some-price:123-type2:aaa-type2:bbb
(type2不止一次使用)。如果有更好的正则表达式请发布。
答案 0 :(得分:1)
您可以使用
^(?!.*[-:](\b(?:city|type2?|price):).*\1)filter:((city:([a-z0-9]+))((-type:([a-z0-9]+))|(-type2:([a-z0-9]+))|(-price:([0-9]+)))*)\s*$
请参阅regex demo
前瞻(?!.*[-:](\b(?:city|type2?|price):).*\1)
将检查(在字符串的开头)并且如果字符串包含(内部某处)-
或:
后跟整个单词(如\b
是单词边界)city
,或type
,或type2
,或price
后跟:
(此键被捕获到群组中) 1使用(...)
)然后使用0+个字符(.*
)然后使用相同的捕获键(因为\1
是对捕获值的反向引用)。
\s*$
将允许尾随空格和字符串结尾,并且将禁止使用未知过滤器。
要缩短模式,请在PCRE / Boost中使用
^(?!.*[-:](\b(?:city|type2?|price):).*\1)filter:(city|type2?|price):([a-z0-9]+)(?:-(?2):(?3))*\s*$
请参阅regex demo(在Ruby中,\g<1>
可以使用\g<2>
代替(?1)
和(?2)
)。
如果正则表达式的风格不同并且不允许递归,请使用
^(?!.*[-:](\b(?:city|type2?|price):).*\1)filter:(?:city|type2?|price):[a-z0-9]+(?:-(?:city|type2?|price):[a-z0-9]+)*$
请参阅another demo