regex 正则表达式限制模式中字符的个数

kadbb459  于 2023-03-31  发布在  其他
关注(0)|答案(4)|浏览(130)

全字符串=

Section 1.1 Some String.........................10

Section 1.2 Some Other String...................11

我只想取出〈Some String〉。〈Some String〉可能包含A-Za-z0-9,一些非单词字符(例如()-,&),还有点。但是点的数量将小于3。
我正在尝试r'Section 1.1 \[A-Za-z0-9,.()&\\s\]\[.\]+\\d+$',但它会给予我整个_字符串。
我正在考虑一种方法来添加一个限制点的出现,如r'Section 1.1 \[A-Za-z0-9,.**{,3}**()&\\s\]\[.\]+\\d+$',但它不起作用。
有人知道吗?

vsaztqbk

vsaztqbk1#

看看你尝试的模式和示例字符串,我认为它应该以匹配点和数字结束。
在这种情况下,您可以使用捕获组:

\bSection 1\.1\s+([^.]+(?:\.[^.]+){0,3})\.+\d+$

说明

  • \bSection 1\.1匹配单词Section,然后匹配1.1
  • \s+匹配1+空格字符
  • (捕获组1
  • [^.]+匹配1+除.以外的字符
  • (?:\.[^.]+){0,3}重复0-3次匹配.,然后是除.以外的1+字符
  • )关闭组1
  • \.+\d+匹配1+个点和1+个数字(使用\.*匹配可选点)
  • $字符串结束

Regex demo|Python demo
re.findall为例,返回捕获组1的值:

import re

pattern = r"\bSection 1\.1\s+([^.]+(?:\.[^.]+){0,3})\.+\d+$"

s = ("Section 1.1 Some String.........................10\n"
    "Section 1.2 Some Other String...................11\n"
    "Section 1.1 I want to catch Som.e Str.i.ng..9\n"
    "Section 1.1 I want to catch Som.e..9\n"
    "Section 1.1 I want to catch Som.e Str.i.ng9\n"
    "Section 1.1 but not So.m.e Str.i.ng.9")
    
print(re.findall(pattern, s, re.M))

输出

['Some String', 'I want to catch Som.e Str.i.ng', 'I want to catch Som.e']
g52tjvyc

g52tjvyc2#

这里有一个基本的版本,可以定制一点,以更好地满足您的需求

"(?:Section \d+\.\d+ )([\sA-Za-z0-9()\-,&\.]*?)(?=\.{4})"gm

这将同时匹配Some StringSome Other String,如果您想专门匹配Section 1.1,请将(?:Section \d+\.\d+)更改为(?:Section 1.1)
如果使用re.findall,则只有Some StringSome Other String是结果。如果使用re.search,则需要指定match.group(1)才能获得结果。
它的工作原理是匹配非捕获组中的Section digit.digit(这就是为什么它不出现在第1组中),与您提到的字符匹配(虽然空格不包含在文本中,但我将其包含在正则表达式中以说明Some String中的空格),并查找它前面的4个.字符以结束匹配。由于4个.字符是先行字符,因此不包括在匹配中。

eulz3vhy

eulz3vhy3#

好吧,这违反了DRY原则,但我不知道有什么方法可以限制单个字符的出现次数,而不限制其他字符:

Section 1\.1 [A-Za-z0-9,()&\s]+[.]?[A-Za-z0-9,()&\s]*[.]?[A-Za-z0-9,()&\s]*[.]?[A-Za-z0-9,()&\s]*[.]+\d+$

这只是重复[A-Za-z0-9,()&\s](不包括点),插入三个[.]?。请注意,第一次出现的[A-Za-z0-9,()&\s]需要至少发生一次(+),但其他的永远不会发生(*)。
你可以测试here
当然,你可以通过编程的方式为任意数量的点构建模式:

def build_pattern(section, dots):
    pattern = r'Section 1\.' + str(section) + ' [A-Za-z0-9,()&\s]+'\
              + '[.]?[A-Za-z0-9,()&\s]*' * dots\
              + '[.]+\d+$'
    return pattern

build_pattern(1, 3)
#Section 1\.1 [A-Za-z0-9,()&\s]+[.]?[A-Za-z0-9,()&\s]*[.]?[A-Za-z0-9,()&\s]*[.]?[A-Za-z0-9,()&\s]*[.]+\d+$
jjjwad0x

jjjwad0x4#

您可以匹配非点字符,后面最多可以跟两组点字符和非点字符:

(?<=Section 1\.1 )[^.]+(?:\.[^.]+){,2}

演示:https://regex101.com/r/qFuPgb/4

相关问题