正则表达式匹配模式并排除字符串列表

3

我是一名新手,对于正则表达式并不熟悉。

基本上我正在尝试创建一个正则表达式来评估我们系统中的URL路径。然而,我们的系统存在已知的错误,导致URL路径变得非常混乱。

理想情况下,URL应该是:

/mobile/retail.*

由于这个 bug,URL 在“/mobile”和“/retail”之间会有“something else”,例如: /mobile(/.*)?/retail 但是挑战在于当“something else”中包含一些我想忽略的单词时,比如 sale、search、lot、login。此时情况应该是这样的:
因此,我有一个测试用例,类似于以下内容:
/mobile/retail -> 匹配
/mobile/retail/something -> 匹配
/mobile/something/retail/something -> 匹配
/mobile/something/retail/something/sale -> 匹配
/mobile/something/something/retail/something/sale -> 匹配
/mobil/sale/something -> 不匹配
/mobile/something/sale/something -> 不匹配
/mobile/something/sale/something/retail -> 不匹配
/mobile/lot/test/retail -> 不匹配
/mobile/test/lot/test/retail -> 不匹配
/mobile/path/test2/test3/testx/lot/test/retail -> 不匹配
我在这个正则表达式上遇到了困难,它不能按照我的要求工作。
/mobile(/(?!sale|search|lot|login).*)?/retail.*

上述正则表达式在以下情况下无法工作:
  • /mobile/something/sale/something/retail
  • /mobile/test/lot/test/retail
  • /mobile/path/test2/test3/testx/lot/test/retail
需要排除的单词是严格的。例如,以下列表应该通过:
  • /mobile/plot/retail
  • /mobile/lots/retail
  • /mobile/lots-of-sale/retail
  • /mobile/sale-item/retail/something/test/sale
  • /mobile/search-prg-item-test/test/retail
非常感激对正则表达式有强大了解并提供任何反馈的人。
2个回答

6

首先尝试这个:

/mobile(?:/(?:(?!sale|search|lot|login)[^/])++)*/retail.*

如果编译失败(您没有指定正则表达式的类型),请尝试:
/mobile(?:/(?:(?!sale|search|lot|login)[^/])+)*/retail.*

说明:

/mobile                     # Match "/mobile"
(?:                         # Match...
 /                          # a slash
 (?:                        # followed by...
  (?!sale|search|lot|login) # (only if these strings arent't present
  [^/]                      # any character except slashes
 )++                        # Match at least one and don't backtrack
)*                          # Do this zero or more times
/retail                     # Then match "/retail"
.*                          # plus whatever follows

2
一个正则表达式,可以重复匹配斜杠之间的部分,其中这样的部分可能不是sale,search,lot或login:
^/mobile(/(?!sale|search|lot|login)[^/]*)*/retail.*

我认为这个比我的更好,因为它可以让像/mobile/plot/retail这样的路径通过(而我的会拒绝)。当然,你的也会拒绝/mobile/lots/retail。@Wilson没有完全说明那些“坏词”需要被严格解释。 - Tim Pietzcker
嗨,Tim,这仅适用于/lot/或/sale/,因此例如,我期望/mobile/plot/retail和/mobile/lots/retail通过。另一个例子..如果是/mobile/saleitem/retail也应该通过。如果有意义的话。 - Wilson
我发现了这个正则表达式:/mobile(?!(.)(/sale/|/search/|/lot/|/login/)./retail).*/retail.*,看起来它是有效的! :) - Wilson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接