正则表达式可以选择匹配文件名末尾的3位数字

时间:2019-03-06 18:54:26

标签: c# regex

我一辈子都想不通如何匹配它们:

File name without 3 digit end.jpg
File name with 3 digit 123.gif
Single 123.jpg
Single.png

但不是这些:

Single 1.jpg
Single 123b.gif
More words 123b.png

到目前为止,我能做到的最好的是这样的表达:

^[^\s]((?!\s{2})(?!,\S).)*\b(\p{L}+|\d{3})\.\w{3}$

但是它不匹配Single.png,仍然匹配Single 123b.gifMore words 123b.png。 我想我知道为什么它行不通,但我不知道如何正确处理,而且我已经苦苦挣扎了2天了。

我的完整规则是:可以选择在文件扩展名的末尾精确地显示3位数字,在文件扩展名中包含3个字母,文件名中不能有两个空格,而在逗号之后但不是逗号之前可以有一个空格。

3 个答案:

答案 0 :(得分:2)

您可以使用包含3个数字或一个非数字序列的交替组,并在其前面加上单词边界声明:

^.*?\b(?:\d{3}|\D+)\.\w{3}$

演示:https://regex101.com/r/A9iSVE/3

答案 1 :(得分:1)

要考虑关于逗号和双精度空格的requiremenet,一种选择是使用2个负号前行断言该字符串不包含双精度空格,并且在逗号前不包含空格。

如果要匹配空格字符而不是单个空格,则可以使用\s

^(?!.*[ ]{2})(?!.* ,).*\b(?:\p{L}+|\d{3})\.\w{3}$

这将匹配

  • ^字符串的开头
  • (?!.*[ ]{2})声明两个空格
  • (?!.* ,)不能声明单个空格和逗号
  • .*\b匹配任何char 0+次,然后匹配单词边界
  • (?:\p{L}+|\d{3})匹配1+次字母或3位数字
  • \.\w{3}匹配.和3个字符的字符
  • $字符串结尾

Regex demo | C# demo

答案 2 :(得分:0)

您可以满足指定的规则而无需回溯(当前接受的答案就是如此)。指定的规则是(为清楚起见,已重新定义):文件名必须满足以下条件:

  • 它不得包含多个空格字符的序列。
  • 逗号后面必须紧跟一个空格字符。
  • 文件名的茎可以有3位后缀。
  • 文件扩展名必须由3个字母组成。

为此目的:

^(?<prefix>[^, ]+(,? [^, ]+)*)(?<suffix>\d\d\d)?(?<extension>.\p{L}\p{L}\p{L})$

会成功,不会花哨的前瞻,不会回溯。分解成碎片,您将得到:

^                  # * match start-of-text, followed by
(?<prefix>         # * a named group, consisting of
  [^,\x20]+        #   * 1 or more characters other than comma or space, followed by
  (                #   * a group, consisting of
    ,?             #     * an optional comma, followed by
    \x20           #     * a single space character, followed by
    [^,\x20]+      #     * 1 or more characters other than comma or space
  )*               #     with the whole group repeated zero or more times
)                  #   followed by
(?<suffix>         # * an optional named group (the suffix), consisting of
  \d\d\d           #   * 3 decimal digits
)?                 #   followed by
(?<extension>      # * a mandatory named group (the filename extension), consisting of
  .\p{L}\p{L}\p{L} #   * 3 letters.
)                  #   followed by
$                  # end-of-text