【问题标题】:Regex: Smallest possible substring match正则表达式:最小可能的子字符串匹配
【发布时间】:2019-12-31 14:35:45
【问题描述】:

我有 url 字符串,例如:

"https://facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/slide_3/"

现在,我需要捕获slide_3 部分,更具体地说,是数字3 的起始位置,限制它应该是一个数字(既不能在任何数字之前也不能在任何数字之后)前面没有“= ”。所以,pageid=2 不应该匹配,而 slide_3 应该匹配。

我用 python 正则表达式试过这个:

p = re.compile('/.*(?<!=)(?<!\d)\d(?!\d).*/')
s = "https://facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/slide_3/"

for m in p.finditer(s):
    print(m.start(), m.group())

结果是

6 //facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/slide_3/

我明白为什么我得到这个,第一个和最后一个“/”满足正则表达式,但子字符串“/slide_3/”也是如此。

如何确保获得与正则表达式匹配的 smallest 子字符串。

为什么这不起作用:

'/[^/](?<!=)(?<!\d)\d(?!\d).*/'

非贪婪运算符 .*? 似乎无法解决问题,因为它不能保证最短的匹配。

应该匹配的字符串:

"https://facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/slide_3/" 
"https://facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/sno3/"
"https://facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/3/"

并且匹配应该分别是 slide_3 , sno3, 3

不应该出现的字符串:

"https://facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/slide/"
"https://facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/slide_33/"
"https://facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/33/"

【问题讨论】:

  • 这里使用正则表达式有什么意义?
  • @OlvinR​​oght 我有多个这样的网址,可能包含也可能不包含上述模式。我需要找到那些做并进一步操纵它们的人
  • 如果我猜对了,模式是 \w_(\d) ?在下划线之后且没有任何数字之后
  • 如果匹配 ^.*?\/slide_\d\/?$ 然后做你的事。

标签: python regex


【解决方案1】:

如果我理解您的问题,那么您可以使用它来检查字符串是否与您预期的模式匹配:

(?:^.*\/)([^\d]*\d)(?:\/?$)

\1 将包含:

slide_3
sno3
3

https://regex101.com/r/h0rNdC/4


这可能有助于获取匹配的索引:Python Regex - How to Get Positions and Values of Matches

【讨论】:

  • 我已经提到我需要匹配正则表达式的最小子字符串,你的答案匹配整个字符串。
  • @Alzio 查看我的编辑。你需要确保只关注\1
  • @Alzio 如果我的回答有帮助,请随时接受它作为正确答案。谢谢。
【解决方案2】:

您可以匹配正斜杠,然后匹配除数字、/= 或换行符之外的任何字符 0 次以上。

在捕获组中捕获单个数字并匹配尾部正斜杠。

要获取比赛的开始和结束索引,例如,您可以使用re.search,它将返回match object

/[^\d/=\r\n]*(\d)/

regex demo | Python demo

例如

import re

regex = r"/[^\d/=\r\n]*(\d)/"
strings = [
    "https://facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/slide_3/",
    "https://facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/sno3/",
    "https://facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/3/",
    "https://facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/slide/",
    "https://facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/slide_33/",
    "https://facty.com/ailments/body/10-home-remedies-for-styes/pageid=2/33/"
]

for s in strings:
    matches = re.search(regex, s)
    if matches:
        print ("Group {groupNum} found at {start}-{end} value:{group}".format(groupNum = 1, start = matches.start(1), end = matches.end(1), group = matches.group(1)))

结果

Group 1 found at 74-75 value:3
Group 1 found at 71-72 value:3
Group 1 found at 68-69 value:3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-08
    • 2022-07-11
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-13
    相关资源
    最近更新 更多