正则表达式包括一件事但排除另一件事

时间:2013-03-18 20:53:32

标签: regex regex-negation

我一直在寻找如何编写正则表达式以包含以指定短语开头的某些URL而排除其他URL时遇到很多麻烦。

我们希望包含以:

开头的网页
/womens
/mens
/kids-clothing/boys
/kids-clothing/girls
/homeware

但是我们想要在网址中排除任何包含/ sXXXXXXX的内容 - 其中X是数字。

到目前为止,我已经写了这篇文章以匹配下面的网址,但它的表现非常奇怪。我应该使用外观还是什么?

\/(womens|mens|kids\-clothing\/boys|kids\-clothing\/boys|homeware).*[^s[0-9]+].*

/homeware/bathroom/s2522424/4-tier-pastel-pop-drawers-approx-91cm-x25cm-x-28cm
/homeware/bathroom/towels-and-bathmats
/homeware/bathroom/towels-and-bathmats/s2506420/boutique-luxury-towels
/homeware/bathroom/towels-and-bathmats?page=3&size=36&cols=4&sort=&id=/homeware/bathroom/towels-and-bathmats&priceRange[min]=1&priceRange[max]=14
/homeware/bathroom?page=3&size=36&cols=4&sort=&id=/homeware/bathroom&priceRange[min]=1&priceRange[max]=35
/homeware/bedroom
/homeware/bedroom/bedding-sets
/homeware/bedroom/bedding-sets/s2471012/striped-reversible-printed-duvet-set
/homeware/bedroom/bedding-sets/s2472706/check-printed-reversible-duvet-set
/homeware/bedroom/bedding-sets/s2475332/union-jack-duvet-set
/kids-clothing/boys/shop-by-age/toddler-3mnths-5yrs/s2520246/boys-lollipop-slogan-t-shirt
/kids-clothing/boys/shop-by-age/toddler-3mnths-5yrs/s2520253/boys-2-pack-dinosaur-t-shirts
/kids-clothing/girls/great-value/sale?page=1&size=36&cols=4&sort=price.asc&id=/kids-clothing/girls/great-value/sale&priceRange[min]=0.5&priceRange[max]=7
/kids-clothing/girls/mini-shops/ballet-outfits
/kids-clothing/girls/shop-by-age/baby--newborn-0-18mths
/kids-clothing/girls/shop-by-age/baby--newborn-0-18mths/s2484120/3-pack-frill-pants-pinks
/kids-clothing/girls/shop-by-age/baby--newborn-0-18mths/s2504431/3-pack-l-s-bodysuit
/mens/categories/tops?page=5&size=36&cols=4&sort=&id=/mens/categories/tops&priceRange[min]=2&priceRange[max]=22.5
/mens/categories/trousers-and-chinos
/mens/categories/trousers-and-chinos/s2438566/easy-essential-cuffed-jogging-bottoms
/mens/categories/trousers-and-chinos/s2438574/easy-essential-cuffed-jogging-bottoms
/mens/categories/trousers-and-chinos/s2458939/regatta-zip-off-lightweight-outdoor-trousers

2 个答案:

答案 0 :(得分:2)

你走在正确的轨道上。否定前瞻会做到这一点:

"^(?!.*\/s\d+)\/(womens|mens|kids\-clothing\/boys|kids\-clothing\/girls|homeware)\/.*"

^锚定到字符串的开头。 (?!.*\/s\d+)表示"/sXXXXXXX"无法出现在字符串中的任何位置,其余部分与您所需的起始标记相匹配。

[^s[0-9]+]无效的原因是[^xyz]只匹配一个字符。您实际上在说的是,您正在寻找的任何字符都不是"s""[""0-9"的任意组合,后跟"]"。例如"s[234[s]"

你需要在字符串的开头放置负向前瞻的原因是没有任何匹配。如果您将其放在\/(womens|mens|kids\-clothing\/boys|kids\-clothing\/girls|homeware)\/.*之后,您仍然可以成功匹配"/sXXXXXXX"之前的所有内容。即对于数据的第1行,您将匹配“/ homeware / bathroom /".

答案 1 :(得分:1)

是的,您需要一个负面的看法:

/^\/(womens|mens|kids\-clothing\/boys|kids\-clothing\/boys|homeware)(?:\/(?:(?!s\d+).)*)+$/gm

如果您一次比较一行,则不需要多行(m)标记。它可能表现得很奇怪,因为你有一个字符类(用方形brakcets表示)嵌套在更方括号内,这是行不通的;你不能嵌套字符类。这已经过测试,可以在改装中使用。