Python 正则表达式在字符串末尾不匹配任何内容

Python 正则表达式在字符串末尾不匹配任何内容,python,regex,regex-group,Python,Regex,Regex Group,我试图匹配文件名中由点分隔的任意数量的文字符号。文字#符号必须在两侧用点分隔,除非它是文件名的最后一个元素。我可以创建一个模式来执行第一个(匹配任何由点包围的文字符号),但我不能同时执行第二个(文件名以文字符号结尾,没有尾随点) 例如,以下内容将匹配: bob.# bob.#. bob.#.exr bob.##.mary.tif bob.####.png 鉴于以下情况不匹配: bob.#string.exr bob.string#.exr 到目前为止,我的模式(用python表示为原始字符串

我试图匹配文件名中由点分隔的任意数量的文字符号。文字#符号必须在两侧用点分隔,除非它是文件名的最后一个元素。我可以创建一个模式来执行第一个(匹配任何由点包围的文字符号),但我不能同时执行第二个(文件名以文字符号结尾,没有尾随点)

例如,以下内容将匹配:

bob.#
bob.#.
bob.#.exr
bob.##.mary.tif
bob.####.png
鉴于以下情况不匹配:

bob.#string.exr
bob.string#.exr
到目前为止,我的模式(用python表示为原始字符串)是:

不幸的是,它与我列表中的第一项不匹配:bob#

我原以为最后一个非捕获组基本上是:

匹配后跟0个或多个字符的文字点

匹配字符串的结尾

但是在regexr.com中测试表明它与bob不匹配#


提前感谢您提供的任何线索

您的表达式似乎工作正常,我仍然会将其修改为一些表达式,可能类似于:

import re

regex = r"^([^.]*)(\.#+)(\..*)?$"

test_str ="""
bob.#
bob.#.
bob.#.exr
bob.##.mary.tif
bob.####.png
Whereas the following would not match:

bob.#string.exr
bob.string#.exr

"""

print(re.findall(regex, test_str,re.M))
输出
如果您希望探索/简化/修改该表达式,它已被删除 在的右上面板上进行了说明 . 如果你愿意,你可以 也可以观看,它将如何匹配 对照一些样本输入


正则表达式电路 可视化正则表达式:


如果您希望它与整个元序列匹配,这里有一个:

import re

pattern = re.compile(r'(\w+\.\#+(?:\.|$)\w*\.*\w*)')
test = ['bob.#', 'bob.#.', 'bob.#.exr', 'bob.##.mary.tif', 'bob.####.png', 'bob.#string.exr', 'bob.string#.exr']
for t in test:
    print(re.findall(pattern, t))
输出:

['bob.#']
['bob.#.']
['bob.#.exr']
['bob.##.mary.tif']
['bob.####.png']
[]
[]
^\w*?\(\.\w*?)*?$

此正则表达式匹配一个点前面的任意数量的单词字符(包括无),匹配一个或多个八进制符号,然后可选地匹配一个点和多个单词/字符

^\w*?\(\.+)(\.\w*?)*$
^锚定到线的起点
\w*?获取所需的任意多个单词字符,但需要的字符数越少越好
\.比赛。字面上
(#+)逐字匹配一个或多个。如果你想数一数它们出现的次数或其他什么,为了你的方便分组。
(      )*?     匹配此组中的零个或多个:
\.一个字点。。。
\w*。。。和零个或多个单词字符,视需要而定。
$确保字符串以该组结尾。

关于此正则表达式的一些注意事项:

  • 只有当行上没有其他字符串时,它才会与您的字符串匹配
  • 八爪兽是分组的,可以在以后提取出来进行计数(或者你想要的任何东西)
  • \w*
    通常比
    *
    更安全、更快-它专门查找单词字符
    a-z、a-z、0-9、
    ,而不是任何符号。作为一般规则,如果你能使你的正则表达式更具体,你应该这样做,以免你冒着风险的恐惧

  • 现在好了。我现在觉得自己有点傻了。我习惯于先在regexr.com上试用我的正则表达式,然后再将它们转换为我的代码。看来这一次这种模式可能让我失望了。谢谢编辑:看起来regexr喜欢你的改进模式。谢谢你的超级清晰的解释和分解!了解\w在速度方面的工作原理是很好的。在我的特殊情况下,我需要匹配可能出现在文件名中的任何字符,包括一些非常深奥的字符,但是您的警告(和链接)非常感谢。您不必使
    \w*?
    不贪婪,因为它不能越过点,您也不必使组的最后一次迭代
    *?$
    不贪婪,因为您正在断言字符串的结尾。@第四鸟可靠的建议-当我减少不贪婪时,它也节省了39个步骤。当我制作未来的正则表达式时,我会记住这一点。
    import re
    
    pattern = re.compile(r'(\w+\.\#+(?:\.|$)\w*\.*\w*)')
    test = ['bob.#', 'bob.#.', 'bob.#.exr', 'bob.##.mary.tif', 'bob.####.png', 'bob.#string.exr', 'bob.string#.exr']
    for t in test:
        print(re.findall(pattern, t))
    
    ['bob.#']
    ['bob.#.']
    ['bob.#.exr']
    ['bob.##.mary.tif']
    ['bob.####.png']
    []
    []