跳转到主要内容

替代正则表达式模块,用于替换re。

项目描述

简介

此regex实现与标准‘re’模块向后兼容,但提供额外的功能。

Python 2

Python 2不再受支持。支持Python 2的最后一个版本是2021.11.10。

PyPy

此模块针对CPython。它假定所有码点具有相同的宽度,因此在U+0000..U+007F之外使用PyPy时可能无法正确行为,因为PyPy将字符串存储为UTF-8。

多线程

regex模块在实例化内置(不可变)字符串类时释放GIL,允许其他Python线程并发运行。也可以通过调用匹配方法并使用关键字参数concurrent=True强制regex模块在匹配时释放GIL。如果字符串在匹配过程中更改,则行为未定义,因此仅在保证不会发生更改时使用它。

Unicode

此模块支持Unicode 16.0.0。支持完整的Unicode大小写折叠。

标志

存在两种标志:作用域和全局。作用域标志只能应用于模式的一部分,可以开启或关闭;全局标志应用于整个模式,只能开启。

作用域标志包括:ASCII (?a)FULLCASE (?f)IGNORECASE (?i)LOCALE (?L)MULTILINE (?m)DOTALL (?s)UNICODE (?u)VERBOSE (?x)WORD (?w)

全局标志包括:BESTMATCH (?b)ENHANCEMATCH (?e)POSIX (?p)REVERSE (?r)VERSION0 (?V0)VERSION1 (?V1)

如果没有指定 ASCIILOCALEUNICODE 标志,默认将根据正则表达式模式是 Unicode 字符串还是字节串来决定是 UNICODE 还是 ASCII

ENHANCEMATCH 标志使模糊匹配尝试改善其找到的下一个匹配的契合度。

BESTMATCH 标志使模糊匹配搜索最佳匹配而不是下一个匹配。

旧版与新版行为比较

为了与 re 模块兼容,本模块具有两种行为

  • 版本 0 行为(旧行为,与 re 模块兼容)

    请注意,re 模块的行为可能会随时间变化,我会尽力在版本 0 中匹配该行为。

    • VERSION0 标志指示。

    • 在 Python 3.7 之前,re 模块中未能正确处理零宽匹配。这些早期版本的行为是:

      • .split 不会在零宽匹配处分割字符串。

      • .sub 在零宽匹配后前进一个字符。

    • 内联标志应用于整个模式,并且无法关闭。

    • 仅支持简单的集合。

    • Unicode 中的不区分大小写的匹配默认使用简单的折叠。

  • 版本 1 行为(新行为,可能与 re 模块不同)

    • VERSION1 标志指示。

    • 正确处理零宽匹配。

    • 内联标志应用于组的末尾或模式末尾,并且可以关闭。

    • 支持嵌套集合和集合运算。

    • Unicode 中的不区分大小写的匹配默认使用完整的折叠。

如果没有指定版本,正则表达式模块将默认使用 regex.DEFAULT_VERSION

Unicode 中的不区分大小写的匹配

正则表达式模块支持 Unicode 中不区分大小写的简单和完整折叠。可以使用 FULLCASE 标志开启完整折叠。请注意,此标志会影响 IGNORECASE 标志的行为;FULLCASE 标志本身不会开启不区分大小写的匹配。

版本 0 行为:默认关闭。

版本 1 行为:默认开启。

嵌套集合和集合运算

由于集合中的未转义"["在含义上的差异,无法同时支持像re模块中使用的简单集合和嵌套集合。

例如,在版本0的行为(简单集合,与re模块兼容)中,模式[[a-z]--[aeiou]]被处理为

  • 包含“[”和字母“a”到“z”的集合

  • 文字“–”

  • 包含字母“a”、“e”、“i”、“o”、“u”的集合

  • 文字“]”

但在版本1的行为(嵌套集合,增强行为)中,则作为

  • 一个集合,它

    • 包含字母“a”到“z”的集合

  • 但排除

    • 包含字母“a”、“e”、“i”、“o”、“u”的集合

版本0行为:仅支持简单集合。

版本1行为:支持嵌套集合和集合操作。

关于命名组的说明

所有组都有一个组号,从1开始。

具有相同组名的组将具有相同的组号,而具有不同组名的组将具有不同的组号。

同一个名字可以被多个组使用,后续捕获将覆盖早期捕获。组的所有捕获都将通过match对象的captures方法可用。

在分支重置的不同分支之间将重用组号,例如(?|(first)|(second))只有一个组1。如果组有不同的组名,那么它们当然会有不同的组号,例如(?|(?P<foo>first)|(?P<bar>second))有组1(“foo”)和组2(“bar”)。

在正则表达式(\s+)(?|(?P<foo>[A-Z]+)|(\w+) (?P<foo>[0-9]+))中有2个组

  • (\s+)是组1。

  • (?P<foo>[A-Z]+)是组2,也称为“foo”。

  • (\w+)是组2,因为使用了分支重置。

  • (?P<foo>[0-9]+)是组2,因为它被命名为“foo”。

如果您想防止(\w+)成为组2,您需要给它命名(不同的名字,不同的组号)。

附加功能

问题号与Python错误跟踪器相关,除非另有说明。

添加了\p{Horiz_Space}\p{Vert_Space}GitHub问题477

\p{Horiz_Space}\p{H}匹配水平空白,而\p{Vert_Space}\p{V}匹配垂直空白。

添加了对条件模式中查找的支持(Hg问题163

条件模式的测试可以是查找。

>>> regex.match(r'(?(?=\d)\d+|\w+)', '123abc')
<regex.Match object; span=(0, 3), match='123'>
>>> regex.match(r'(?(?=\d)\d+|\w+)', 'abc123')
<regex.Match object; span=(0, 6), match='abc123'>

这并不完全等同于在成对选择的第一分支中放置查找。

>>> print(regex.match(r'(?:(?=\d)\d+\b|\w+)', '123abc'))
<regex.Match object; span=(0, 6), match='123abc'>
>>> print(regex.match(r'(?(?=\d)\d+\b|\w+)', '123abc'))
None

在第一个示例中,查找匹配了,但第一分支的其余部分未匹配,因此尝试了第二分支,而在第二个示例中,查找匹配了,第一分支未匹配,但第二分支没有尝试。

添加了POSIX匹配(最左最长匹配)(Hg问题150

POSIX标准规定正则表达式应返回最左最长匹配。可以使用POSIX标志将其打开。

>>> # Normal matching.
>>> regex.search(r'Mr|Mrs', 'Mrs')
<regex.Match object; span=(0, 2), match='Mr'>
>>> regex.search(r'one(self)?(selfsufficient)?', 'oneselfsufficient')
<regex.Match object; span=(0, 7), match='oneself'>
>>> # POSIX matching.
>>> regex.search(r'(?p)Mr|Mrs', 'Mrs')
<regex.Match object; span=(0, 3), match='Mrs'>
>>> regex.search(r'(?p)one(self)?(selfsufficient)?', 'oneselfsufficient')
<regex.Match object; span=(0, 17), match='oneselfsufficient'>

请注意,这将需要更长的时间来找到匹配项,因为当它在某个位置找到匹配项时,它不会立即返回,而是会继续寻找那里是否还有更长的匹配项。

添加了(?(DEFINE)...)Hg问题152

如果没有名为“DEFINE”的组,则以下内容将被忽略,除非在其中定义的任何组都可以被调用,并且组编号的正常规则仍然适用。

>>> regex.search(r'(?(DEFINE)(?P<quant>\d+)(?P<item>\w+))(?&quant) (?&item)', '5 elephants')
<regex.Match object; span=(0, 11), match='5 elephants'>

添加了(*PRUNE)(*SKIP)(*FAIL)Hg问题153

(*PRUNE)丢弃到该点为止的所有回溯信息。在原子组或前瞻中使用时,它不会影响外部模式。

(*SKIP)类似于(*PRUNE),除了它还设置下一次尝试匹配文本的位置。在原子组或前瞻中使用时,它不会影响外部模式。

(*FAIL)导致立即回溯。(*F)是一个允许的缩写。

添加了\KHg问题151

保留从\K出现位置开始直到整个匹配的部分;其前面的部分将被丢弃。

它不影响组返回的内容。

>>> m = regex.search(r'(\w\w\K\w\w\w)', 'abcdef')
>>> m[0]
'cde'
>>> m[1]
'abcde'
>>>
>>> m = regex.search(r'(?r)(\w\w\K\w\w\w)', 'abcdef')
>>> m[0]
'bc'
>>> m[1]
'bcdef'

expandfsubf/subfn添加了捕获子索引(Hg问题133

您可以使用子索引获取重复组的捕获。

>>> m = regex.match(r"(\w)+", "abc")
>>> m.expandf("{1}")
'c'
>>> m.expandf("{1[0]} {1[1]} {1[2]}")
'a b c'
>>> m.expandf("{1[-1]} {1[-2]} {1[-3]}")
'c b a'
>>>
>>> m = regex.match(r"(?P<letter>\w)+", "abc")
>>> m.expandf("{letter}")
'c'
>>> m.expandf("{letter[0]} {letter[1]} {letter[2]}")
'a b c'
>>> m.expandf("{letter[-1]} {letter[-2]} {letter[-3]}")
'c b a'

添加了对使用(?P=...)通过编号引用组的功能

这是在现有的\g<...>的基础上增加的。

修复了与位置敏感正则表达式的处理

LOCALE标志旨在用于旧代码,并具有有限的支持。您仍然建议使用Unicode。

添加了部分匹配(Hg问题102

部分匹配是匹配到字符串末尾的匹配,但该字符串已被截断,您想知道如果字符串没有被截断,是否可能有一个完整的匹配。

部分匹配通过带有partial关键字参数的matchsearchfullmatchfinditer得到支持。

匹配对象有一个partial属性,如果它是部分匹配,则该属性为True

例如,如果您想要用户输入一个4位数,并在输入时逐个检查它

>>> pattern = regex.compile(r'\d{4}')

>>> # Initially, nothing has been entered:
>>> print(pattern.fullmatch('', partial=True))
<regex.Match object; span=(0, 0), match='', partial=True>

>>> # An empty string is OK, but it's only a partial match.
>>> # The user enters a letter:
>>> print(pattern.fullmatch('a', partial=True))
None
>>> # It'll never match.

>>> # The user deletes that and enters a digit:
>>> print(pattern.fullmatch('1', partial=True))
<regex.Match object; span=(0, 1), match='1', partial=True>
>>> # It matches this far, but it's only a partial match.

>>> # The user enters 2 more digits:
>>> print(pattern.fullmatch('123', partial=True))
<regex.Match object; span=(0, 3), match='123', partial=True>
>>> # It matches this far, but it's only a partial match.

>>> # The user enters another digit:
>>> print(pattern.fullmatch('1234', partial=True))
<regex.Match object; span=(0, 4), match='1234'>
>>> # It's a complete match.

>>> # If the user enters another digit:
>>> print(pattern.fullmatch('12345', partial=True))
None
>>> # It's no longer a match.

>>> # This is a partial match:
>>> pattern.match('123', partial=True).partial
True

>>> # This is a complete match:
>>> pattern.match('1233', partial=True).partial
False

*运算符与sub()不正确地工作(Hg问题106

有时不清楚如何处理零宽匹配。例如,应该.*匹配在匹配了>0个字符之后的0个字符吗?

>>> regex.sub('.*', 'x', 'test')
'xx'
>>> regex.sub('.*?', '|', 'test')
'|||||||||'

添加了capturesdictHg问题86

capturesdictgroupdictcaptures的组合

groupdict返回一个包含命名组和这些组的最后一个捕获的字典。

captures返回一个包含一个组的所有捕获的列表。

capturesdict返回一个包含命名组和这些组的所有捕获列表的字典。

>>> m = regex.match(r"(?:(?P<word>\w+) (?P<digits>\d+)\n)+", "one 1\ntwo 2\nthree 3\n")
>>> m.groupdict()
{'word': 'three', 'digits': '3'}
>>> m.captures("word")
['one', 'two', 'three']
>>> m.captures("digits")
['1', '2', '3']
>>> m.capturesdict()
{'word': ['one', 'two', 'three'], 'digits': ['1', '2', '3']}

添加了allcapturesallspansGit问题474

allcaptures返回所有组的所有捕获的列表。

allspans返回所有组的所有捕获的跨度列表。

>>> m = regex.match(r"(?:(?P<word>\w+) (?P<digits>\d+)\n)+", "one 1\ntwo 2\nthree 3\n")
>>> m.allcaptures()
(['one 1\ntwo 2\nthree 3\n'], ['one', 'two', 'three'], ['1', '2', '3'])
>>> m.allspans()
([(0, 20)], [(0, 3), (6, 9), (12, 17)], [(4, 5), (10, 11), (18, 19)])

允许组名称重复(《Hg问题87》)

组名称可以重复。

>>> # With optional groups:
>>>
>>> # Both groups capture, the second capture 'overwriting' the first.
>>> m = regex.match(r"(?P<item>\w+)? or (?P<item>\w+)?", "first or second")
>>> m.group("item")
'second'
>>> m.captures("item")
['first', 'second']
>>> # Only the second group captures.
>>> m = regex.match(r"(?P<item>\w+)? or (?P<item>\w+)?", " or second")
>>> m.group("item")
'second'
>>> m.captures("item")
['second']
>>> # Only the first group captures.
>>> m = regex.match(r"(?P<item>\w+)? or (?P<item>\w+)?", "first or ")
>>> m.group("item")
'first'
>>> m.captures("item")
['first']
>>>
>>> # With mandatory groups:
>>>
>>> # Both groups capture, the second capture 'overwriting' the first.
>>> m = regex.match(r"(?P<item>\w*) or (?P<item>\w*)?", "first or second")
>>> m.group("item")
'second'
>>> m.captures("item")
['first', 'second']
>>> # Again, both groups capture, the second capture 'overwriting' the first.
>>> m = regex.match(r"(?P<item>\w*) or (?P<item>\w*)", " or second")
>>> m.group("item")
'second'
>>> m.captures("item")
['', 'second']
>>> # And yet again, both groups capture, the second capture 'overwriting' the first.
>>> m = regex.match(r"(?P<item>\w*) or (?P<item>\w*)", "first or ")
>>> m.group("item")
''
>>> m.captures("item")
['first', '']

添加了 fullmatch(《问题#16203》)

fullmatch 的行为与 match 类似,但它必须匹配整个字符串。

>>> print(regex.fullmatch(r"abc", "abc").span())
(0, 3)
>>> print(regex.fullmatch(r"abc", "abcx"))
None
>>> print(regex.fullmatch(r"abc", "abcx", endpos=3).span())
(0, 3)
>>> print(regex.fullmatch(r"abc", "xabcy", pos=1, endpos=4).span())
(1, 4)
>>>
>>> regex.match(r"a.*?", "abcd").group(0)
'a'
>>> regex.fullmatch(r"a.*?", "abcd").group(0)
'abcd'

添加了 subfsubfn

subfsubfn 分别是 subsubn 的替代方案。当传递一个替换字符串时,它们将其视为格式字符串。

>>> regex.subf(r"(\w+) (\w+)", "{0} => {2} {1}", "foo bar")
'foo bar => bar foo'
>>> regex.subf(r"(?P<word1>\w+) (?P<word2>\w+)", "{word2} {word1}", "foo bar")
'bar foo'

添加了 expandf 到匹配对象

expandfexpand 的替代方案。当传递一个替换字符串时,它将其视为格式字符串。

>>> m = regex.match(r"(\w+) (\w+)", "foo bar")
>>> m.expandf("{0} => {2} {1}")
'foo bar => bar foo'
>>>
>>> m = regex.match(r"(?P<word1>\w+) (?P<word2>\w+)", "foo bar")
>>> m.expandf("{word2} {word1}")
'bar foo'

分离搜索的字符串

匹配对象通过其 string 属性包含对搜索的字符串的引用。使用 detach_string 方法将“分离”该字符串,使其可用于垃圾回收,如果该字符串非常大,这可能会节省宝贵的内存。

>>> m = regex.search(r"\w+", "Hello world")
>>> print(m.group())
Hello
>>> print(m.string)
Hello world
>>> m.detach_string()
>>> print(m.group())
Hello
>>> print(m.string)
None

递归模式(《Hg问题27》)

支持递归和重复模式。

(?R)(?0) 尝试递归地匹配整个正则表达式。 (?1)(?2) 等,尝试匹配相关的组。

(?&name) 尝试匹配命名组。

>>> regex.match(r"(Tarzan|Jane) loves (?1)", "Tarzan loves Jane").groups()
('Tarzan',)
>>> regex.match(r"(Tarzan|Jane) loves (?1)", "Jane loves Tarzan").groups()
('Jane',)

>>> m = regex.search(r"(\w)(?:(?R)|(\w?))\1", "kayak")
>>> m.group(0, 1, 2)
('kayak', 'k', None)

前两个例子显示了组内的子模式是如何被重复使用的,但它本身不是一个组。换句话说,“"(Tarzan|Jane) loves (?1)”与“"(Tarzan|Jane) loves (?:Tarzan|Jane)”等价。

可以回溯到递归或重复的组。

如果有多个组具有相同的组名称或组编号,则不能调用该组("模糊的组引用")。

也支持替代形式 (?P>name)(?P&name)

支持完整的Unicode大小写折叠

在版本1的行为中,正则表达式模块在Unicode中进行不区分大小写的匹配时使用完整的大小写折叠。

>>> regex.match(r"(?iV1)strasse", "stra\N{LATIN SMALL LETTER SHARP S}e").span()
(0, 6)
>>> regex.match(r"(?iV1)stra\N{LATIN SMALL LETTER SHARP S}e", "STRASSE").span()
(0, 7)

在版本0的行为中,它使用简单的大小写折叠以与re模块保持向后兼容。

近似“模糊”匹配(《Hg问题12》、《Hg问题41》、《Hg问题109》)

正则表达式通常尝试精确匹配,但有时需要近似或“模糊”匹配,这对于搜索的文本可能包含插入、删除或替换字符的错误形式的情况。

模糊正则表达式指定允许哪种类型的错误,并且可选地,每种类型的最小和最大或仅最大允许数量。(不能仅指定最小。)

3种错误类型是

  • 插入,用“i”表示

  • 删除,用“d”表示

  • 替换,用“s”表示

此外,“e”表示任何类型的错误。

正则表达式项的模糊性在项之后用“{”和“}”指定。

示例

  • foo 精确匹配“foo”

  • (?:foo){i} 匹配“foo”,允许插入

  • (?:foo){d} 匹配“foo”,允许删除

  • (?:foo){s} 匹配“foo”,允许替换

  • (?:foo){i,s} 匹配“foo”,允许插入和替换

  • (?:foo){e} 匹配“foo”,允许错误

如果指定了某种类型的错误,则未指定的任何类型将 不允许

以下示例中,我将省略项目,只写模糊性。

  • {d<=3} 允许最多 3 次删除,但不允许其他类型。

  • {i<=1,s<=2} 允许最多 1 次插入和最多 2 次替换,但不允许删除。

  • {1<=e<=3} 允许至少 1 次错误,最多 3 次错误。

  • {i<=2,d<=2,e<=3} 允许最多 2 次插入,最多 2 次删除,总共最多 3 次错误,但不允许替换。

还可以指定每种类型错误的成本以及允许的最大总成本。

示例

  • {2i+2d+1s<=4} 每次插入成本 2,每次删除成本 2,每次替换成本 1,总成本不得超过 4。

  • {i<=1,d<=1,s<=1,2i+2d+1s<=4} 最多 1 次插入,最多 1 次删除,最多 1 次替换;每次插入成本 2,每次删除成本 2,每次替换成本 1,总成本不得超过 4。

如果想要一个排他性的最小值或最大值,可以用“<”代替“<=”。

可以为替换或插入的字符添加一个测试。

示例

  • {s<=2:[a-z]} 最多 2 次替换,替换的字符必须在字符集 [a-z] 中。

  • {s<=2,i<=3:\d} 最多 2 次替换,最多 3 次插入,插入的必须是数字。

默认情况下,模糊匹配搜索第一个符合给定约束的匹配项。 ENHANCEMATCH 标志将使它尝试改进(即减少错误的数量)已找到的匹配。

BESTMATCH 标志将使其搜索最佳匹配。

其他示例

  • regex.search("(dog){e}", "cat and dog")[1] 返回 "cat",因为那匹配 "dog" 有 3 个错误(允许无限数量的错误)。

  • regex.search("(dog){e<=1}", "cat and dog")[1] 返回 " dog"(带前导空格),因为那匹配 "dog" 有 1 个错误,在限制范围内。

  • regex.search("(?e)(dog){e<=1}", "cat and dog")[1] 返回 "dog"(不带前导空格),因为模糊搜索匹配 " dog" 有 1 个错误,在限制范围内,然后 (?e) 尝试更好的匹配。

在前两个示例中,字符串的后面有完美的匹配,但在这两种情况下,都不是第一个可能的匹配。

匹配对象有一个 fuzzy_counts 属性,它给出了替换、插入和删除的总数。

>>> # A 'raw' fuzzy match:
>>> regex.fullmatch(r"(?:cats|cat){e<=1}", "cat").fuzzy_counts
(0, 0, 1)
>>> # 0 substitutions, 0 insertions, 1 deletion.

>>> # A better match might be possible if the ENHANCEMATCH flag used:
>>> regex.fullmatch(r"(?e)(?:cats|cat){e<=1}", "cat").fuzzy_counts
(0, 0, 0)
>>> # 0 substitutions, 0 insertions, 0 deletions.

匹配对象还有一个 fuzzy_changes 属性,它给出了替换、插入和删除位置的元组。

>>> m = regex.search('(fuu){i<=2,d<=2,e<=5}', 'anaconda foo bar')
>>> m
<regex.Match object; span=(7, 10), match='a f', fuzzy_counts=(0, 2, 2)>
>>> m.fuzzy_changes
([], [7, 8], [10, 11])

这意味着,如果字符串的匹配部分是

'anacondfuuoo bar'

它将是一个完全匹配。

但是,在第 7 和 8 个位置有插入

'anaconda fuuoo bar'
        ^^

在第 10 和 11 个位置有删除

'anaconda f~~oo bar'
           ^^

所以实际的字符串是

'anaconda foo bar'

命名列表 \L<name> (Hg issue 11)

有时你可能需要在正则表达式中包含一个选项列表(实际上,是一个集合)。

一种方法是构建如下模式

>>> p = regex.compile(r"first|second|third|fourth|fifth")

但如果列表很大,解析生成的正则表达式可能需要相当多的时间,还必须注意字符串被正确转义并正确排序,例如,“cats”在“cat”之前。

新的替代方法是使用命名列表

>>> option_set = ["first", "second", "third", "fourth", "fifth"]
>>> p = regex.compile(r"\L<options>", options=option_set)

项目顺序无关紧要,它们被视为一个集合。命名列表是作为模式对象的 .named_lists 属性提供的

>>> print(p.named_lists)
{'options': frozenset({'third', 'first', 'fifth', 'fourth', 'second'})}

如果有任何未使用的关键字参数,除非你告知它,否则将引发 ValueError

>>> option_set = ["first", "second", "third", "fourth", "fifth"]
>>> p = regex.compile(r"\L<options>", options=option_set, other_options=[])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python310\lib\site-packages\regex\regex.py", line 353, in compile
    return _compile(pattern, flags, ignore_unused, kwargs, cache_pattern)
  File "C:\Python310\lib\site-packages\regex\regex.py", line 500, in _compile
    complain_unused_args()
  File "C:\Python310\lib\site-packages\regex\regex.py", line 483, in complain_unused_args
    raise ValueError('unused keyword argument {!a}'.format(any_one))
ValueError: unused keyword argument 'other_options'
>>> p = regex.compile(r"\L<options>", options=option_set, other_options=[], ignore_unused=True)
>>> p = regex.compile(r"\L<options>", options=option_set, other_options=[], ignore_unused=False)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python310\lib\site-packages\regex\regex.py", line 353, in compile
    return _compile(pattern, flags, ignore_unused, kwargs, cache_pattern)
  File "C:\Python310\lib\site-packages\regex\regex.py", line 500, in _compile
    complain_unused_args()
  File "C:\Python310\lib\site-packages\regex\regex.py", line 483, in complain_unused_args
    raise ValueError('unused keyword argument {!a}'.format(any_one))
ValueError: unused keyword argument 'other_options'
>>>

单词的开始和结束

\m 匹配单词的开始。

\M 匹配单词的结束。

\b 进行比较,它匹配单词的开始或结束。

Unicode行分隔符

通常只有一个行分隔符是 \n\x0A),但如果 WORD 标志被打开,则行分隔符是 \x0D\x0A\x0A\x0B\x0C\x0D,以及当使用 Unicode 时,还有 \x85\u2028\u2029

这会影响正则表达式的点 ".",如果没有打开 DOTALL 标志,它匹配任何字符,除了行分隔符。它还影响行锚点 ^$(在多行模式中)。

集合运算符

仅第 1 版行为

已添加集合运算符,并且一个集合 [...] 可以包含嵌套集合。

运算符的优先级顺序如下

  • || 用于并集(“x||y”表示“x 或 y”)

  • ~~ (双波浪号)用于对称差集(“x~~y”表示“x 或 y,但不能同时两者都有”)

  • && 用于交集(“x&&y”表示“x 和 y”)

  • --(双破折号)用于差集(“x–y”表示“x 但不是 y”)

隐式并集,即简单并置,例如 [ab],具有最高优先级。因此,[ab&&cd][[a||b]&&[c||d]] 相同。

示例

  • [ab] # 包含‘a’和‘b’的集合

  • [a-z] # 包含‘a’ .. ‘z’的集合

  • [[a-z]--[qw]] # 包含‘a’ .. ‘z’,但不包含‘q’或‘w’的集合

  • [a-z--qw] # 与上面相同

  • [\p{L}--QW] # 不包含‘Q’和‘W’的所有字母的集合

  • [\p{N}--[0-9]] # 不包含‘0’ .. ‘9’的所有数字的集合

  • [\p{ASCII}&&\p{Letter}] # 包含所有ASCII和字母字符的集合

regex.escape (问题 #2650

regex.escape 有一个额外的关键字参数 special_only。当为 True 时,仅转义“特殊”正则表达式字符,例如“?”。

>>> regex.escape("foo!?", special_only=False)
'foo\\!\\?'
>>> regex.escape("foo!?", special_only=True)
'foo!\\?'

regex.escape (Hg问题 249

regex.escape 有一个额外的关键字参数 literal_spaces。当为 True 时,不转义空格。

>>> regex.escape("foo bar!?", literal_spaces=False)
'foo\\ bar!\\?'
>>> regex.escape("foo bar!?", literal_spaces=True)
'foo bar!\\?'

重复捕获(问题 #7132

匹配对象具有额外的方法,这些方法返回关于重复组所有成功匹配的信息。这些方法包括:

  • matchobject.captures([group1, ...])

    • 返回一个列表,包含在组或组中匹配的字符串。与 matchobject.group([group1, ...]) 进行比较。

  • matchobject.starts([group])

    • 返回一个列表,包含开始位置。与 matchobject.start([group]) 进行比较。

  • matchobject.ends([group])

    • 返回一个列表,包含结束位置。与 matchobject.end([group]) 进行比较。

  • matchobject.spans([group])

    • 返回一个列表,包含范围。与 matchobject.span([group]) 进行比较。

>>> m = regex.search(r"(\w{3})+", "123456789")
>>> m.group(1)
'789'
>>> m.captures(1)
['123', '456', '789']
>>> m.start(1)
6
>>> m.starts(1)
[0, 3, 6]
>>> m.end(1)
9
>>> m.ends(1)
[3, 6, 9]
>>> m.span(1)
(6, 9)
>>> m.spans(1)
[(0, 3), (3, 6), (6, 9)]

原子分组 (?>...) (问题 #433030)

如果随后的模式失败,则整个子模式将失败。

占有量词

(?:...)?+ ; (?:...)*+ ; (?:...)++ ; (?:...){min,max}+

子模式匹配到“max”次。如果随后的模式失败,则所有重复的子模式将整体失败。例如,(?:...)++ 等价于 (?>(?:...)+)

作用域标志 (问题 #433028)

(?flags-flags:...)

标志仅应用于子模式。标志可以开启或关闭。

“单词”字符的定义 (问题 #1693050)

“单词”字符的定义已扩展至Unicode。它符合 http://www.unicode.org/reports/tr29/ 上的Unicode规范。

可变长度后视匹配

后视匹配可以匹配可变长度的字符串。

regex.split, regex.sub 和 regex.subn 的 flags 参数 (问题 #3482)

regex.splitregex.subregex.subn 支持一个“flags”参数。

regex.sub 和 regex.subn 的 pos 和 endpos 参数

regex.subregex.subn 支持‘pos’和‘endpos’参数。

regex.findall 和 regex.finditer 的“Overlapped”参数

regex.findallregex.finditer 支持一个“overlapped”标志,允许重叠匹配。

Splititer

regex.splititer 已添加。它是 regex.split 的生成器等价物。

为组使用匹配对象的索引

匹配对象可以通过索引和切片访问组。

>>> m = regex.search(r"(?P<before>.*?)(?P<num>\d+)(?P<after>.*)", "pqr123stu")
>>> print(m["before"])
pqr
>>> print(len(m))
4
>>> print(m[:])
('pqr123stu', 'pqr', '123', 'stu')

命名组

可以使用 (?<name>...) 以及现有的 (?P<name>...) 来命名组。

组引用

可以在模式内使用 \g<name> 来引用组。这也允许存在超过99个组。

命名字符 \N{name}

支持命名字符。注意,只有Python的Unicode数据库所知的那些会被识别。

Unicode代码点属性,包括脚本和块

\p{property=value}; \P{property=value}; \p{value} ; \P{value}

支持许多Unicode属性,包括块和脚本。 \p{property=value}\p{property:value} 匹配属性 property 的值为 value 的字符。 \p{property=value} 的逆是 \P{property=value}\p{^property=value}

如果使用简写形式 \p{value},则按照以下顺序检查属性:General_CategoryScriptBlock、二进制属性。

  • 拉丁,表示“拉丁”脚本(Script=Latin)。

  • BasicLatin,表示“BasicLatin”块(Block=BasicLatin)。

  • Alphabetic,表示“Alphabetic”二进制属性(Alphabetic=Yes)。

Is 开头的简写形式表示脚本或二进制属性

  • IsLatin,表示“拉丁”脚本(Script=Latin)。

  • IsAlphabetic,表示“Alphabetic”二进制属性(Alphabetic=Yes)。

In 开头的简写形式表示块属性

  • InBasicLatin,表示“BasicLatin”块(Block=BasicLatin)。

POSIX字符类

[[:alpha:]][[:^alpha:]]

POSIX字符类受到支持。这些通常被视为 \p{...} 的另一种形式。

例外是 alnumdigitpunctxdigit,它们的定义与Unicode不同。

[[:alnum:]] 等同于 \p{posix_alnum}

[[:digit:]] 等同于 \p{posix_digit}

[[:punct:]] 等同于 \p{posix_punct}

[[:xdigit:]] 等同于 \p{posix_xdigit}

搜索锚点 \G

已添加搜索锚点。它匹配每个搜索开始/继续的位置,可用于连续匹配或在负变长后视中限制后视的范围。

>>> regex.findall(r"\w{2}", "abcd ef")
['ab', 'cd', 'ef']
>>> regex.findall(r"\G\w{2}", "abcd ef")
['ab', 'cd']
  • 搜索从位置 0 开始并匹配“ab”。

  • 搜索从位置 2 开始并匹配“cd”。

  • 搜索从位置 4 开始并无法匹配任何字母。

  • 锚点阻止搜索开始位置的前移,因此没有更多结果。

反向搜索

搜索也可以反向进行

>>> regex.findall(r".", "abc")
['a', 'b', 'c']
>>> regex.findall(r"(?r).", "abc")
['c', 'b', 'a']

请注意,反向搜索的结果不一定是正向搜索的逆序

>>> regex.findall(r"..", "abcde")
['ab', 'cd']
>>> regex.findall(r"(?r)..", "abcde")
['de', 'bc']

匹配单个图形 \X

图形匹配器受到支持。它符合 Unicode 规范,可在 http://www.unicode.org/reports/tr29/ 上找到。

分支重置 (?|...|...)

组号将在备选方案之间重复使用,但具有不同名称的组将具有不同的组号。

>>> regex.match(r"(?|(first)|(second))", "first").groups()
('first',)
>>> regex.match(r"(?|(first)|(second))", "second").groups()
('second',)

请注意,只有一个组。

默认Unicode单词边界

WORD 标志将“单词边界”的定义更改为默认 Unicode 单词边界。这适用于 \b\B

超时

匹配方法和函数支持超时。超时(以秒为单位)适用于整个操作。

>>> from time import sleep
>>>
>>> def fast_replace(m):
...     return 'X'
...
>>> def slow_replace(m):
...     sleep(0.5)
...     return 'X'
...
>>> regex.sub(r'[a-z]', fast_replace, 'abcde', timeout=2)
'XXXXX'
>>> regex.sub(r'[a-z]', slow_replace, 'abcde', timeout=2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python310\lib\site-packages\regex\regex.py", line 278, in sub
    return pat.sub(repl, string, count, pos, endpos, concurrent, timeout)
TimeoutError: regex timed out

项目详情


发行历史 发布通知 | RSS 源

下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码发行版

regex-2024.9.11.tar.gz (399.4 kB 查看哈希值)

上传时间 源代码

构建发行版

regex-2024.9.11-cp313-cp313-win_amd64.whl (273.5 kB 查看哈希值)

上传时间 CPython 3.13 Windows x86-64

regex-2024.9.11-cp313-cp313-win32.whl (262.0 kB 查看哈希值)

上传时间 CPython 3.13 Windows x86

regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl (787.4 kB 查看哈希值)

上传时间 CPython 3.13 musllinux: musl 1.2+ x86-64

regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl (859.6 kB 查看哈希值)

上传时间 CPython 3.13 musllinux: musl 1.2+ s390x

regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl (860.4 kB 查看哈希值)

上传时间 CPython 3.13 musllinux: musl 1.2+ ppc64le

regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl (790.3 kB 查看哈希值)

上传时间 CPython 3.13 musllinux: musl 1.2+ i686

regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl (782.5 kB 查看哈希值)

上传时间 CPython 3.13 musllinux: musl 1.2+ ARM64

regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (797.0 kB 查看哈希值)

上传时间 CPython 3.13 manylinux: glibc 2.17+ x86-64

regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl (823.5 kB 查看哈希值)

上传时间 CPython 3.13 manylinux: glibc 2.17+ s390x

regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (835.8 kB 查看哈希值)

上传时间 CPython 3.13 manylinux: glibc 2.17+ ppc64le

regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (795.3 kB 查看哈希值)

上传时间 CPython 3.13 manylinux: glibc 2.17+ ARM64

regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (784.1 kB 查看哈希值)

上传时间 CPython 3.13 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl (284.6 kB 查看哈希值)

上传时间 CPython 3.13 macOS 11.0+ ARM64

regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl (288.1 kB 查看哈希值)

上传时间 CPython 3.13 macOS 10.13+ x86-64

regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl (483.4 kB 查看哈希值)

上传时间 CPython 3.13 macOS 10.13+ universal2 (ARM64, x86-64)

regex-2024.9.11-cp312-cp312-win_amd64.whl (273.5 kB 查看哈希值)

上传时间 CPython 3.12 Windows x86-64

regex-2024.9.11-cp312-cp312-win32.whl (262.1 kB 查看哈希值)

上传时间 CPython 3.12 Windows x86

regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl (787.3 kB 查看哈希值)

上传时间 CPython 3.12 musllinux: musl 1.2+ x86-64

regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl (859.4 kB 查看哈希值)

上传于 CPython 3.12 musllinux: musl 1.2+ s390x

regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl (860.2 kB 查看哈希值)

上传于 CPython 3.12 musllinux: musl 1.2+ ppc64le

regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl (790.3 kB 查看哈希值)

上传于 CPython 3.12 musllinux: musl 1.2+ i686

regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl (782.5 kB 查看哈希值)

上传于 CPython 3.12 musllinux: musl 1.2+ ARM64

regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (797.0 kB 查看哈希值)

上传于 CPython 3.12 manylinux: glibc 2.17+ x86-64

regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl (823.5 kB 查看哈希值)

上传于 CPython 3.12 manylinux: glibc 2.17+ s390x

regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (835.8 kB 查看哈希值)

上传于 CPython 3.12 manylinux: glibc 2.17+ ppc64le

regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (795.2 kB 查看哈希值)

上传于 CPython 3.12 manylinux: glibc 2.17+ ARM64

regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (784.1 kB 查看哈希值)

上传于 CPython 3.12 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl (284.7 kB 查看哈希值)

上传于 CPython 3.12 macOS 11.0+ ARM64

regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl (288.2 kB 查看哈希值)

上传于 CPython 3.12 macOS 10.9+ x86-64

regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl (483.6 kB 查看哈希值)

上传于 CPython 3.12 macOS 10.9+ universal2 (ARM64, x86-64)

regex-2024.9.11-cp311-cp311-win_amd64.whl (274.0 kB 查看哈希值)

上传于 CPython 3.11 Windows x86-64

regex-2024.9.11-cp311-cp311-win32.whl (261.6 kB 查看哈希值)

上传于 CPython 3.11 Windows x86

regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl (781.9 kB 查看哈希值)

上传于 CPython 3.11 musllinux: musl 1.2+ x86-64

regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl (855.9 kB 查看哈希值)

上传于 CPython 3.11 musllinux: musl 1.2+ s390x

regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl (853.7 kB 查看哈希值)

上传于 CPython 3.11 musllinux: musl 1.2+ ppc64le

regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl (784.6 kB 查看哈希值)

上传于 CPython 3.11 musllinux: musl 1.2+ i686

regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl (778.2 kB 查看哈希值)

上传于 CPython 3.11 musllinux: musl 1.2+ ARM64

regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (792.8 kB 查看哈希值)

上传于 CPython 3.11 manylinux: glibc 2.17+ x86-64

regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl (818.6 kB 查看哈希值)

上传于 CPython 3.11 manylinux: glibc 2.17+ s390x

regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (832.6 kB 查看哈希)

上传于 CPython 3.11 manylinux: glibc 2.17+ ppc64le

regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (791.8 kB 查看哈希)

上传于 CPython 3.11 manylinux: glibc 2.17+ ARM64

regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (781.1 kB 查看哈希)

上传于 CPython 3.11 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl (284.6 kB 查看哈希)

上传于 CPython 3.11 macOS 11.0+ ARM64

regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl (287.4 kB 查看哈希)

上传于 CPython 3.11 macOS 10.9+ x86-64

regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl (482.5 kB 查看哈希)

上传于 CPython 3.11 macOS 10.9+ universal2 (ARM64, x86-64)

regex-2024.9.11-cp310-cp310-win_amd64.whl (274.0 kB 查看哈希)

上传于 CPython 3.10 Windows x86-64

regex-2024.9.11-cp310-cp310-win32.whl (261.6 kB 查看哈希)

上传于 CPython 3.10 Windows x86

regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl (773.9 kB 查看哈希)

上传于 CPython 3.10 musllinux: musl 1.2+ x86-64

regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl (845.4 kB 查看哈希)

上传于 CPython 3.10 musllinux: musl 1.2+ s390x

regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl (845.4 kB 查看哈希值)

上传于 CPython 3.10 musllinux: musl 1.2+ ppc64le

regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl (777.5 kB 查看哈希值)

上传于 CPython 3.10 musllinux: musl 1.2+ i686

regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl (769.2 kB 查看哈希值)

上传于 CPython 3.10 musllinux: musl 1.2+ ARM64

regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (782.7 kB 查看哈希值)

上传于 CPython 3.10 manylinux: glibc 2.17+ x86-64

regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl (810.0 kB 查看哈希值)

上传于 CPython 3.10 manylinux: glibc 2.17+ s390x

regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (823.2 kB 查看哈希值)

上传于 CPython 3.10 manylinux: glibc 2.17+ ppc64le

regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (783.2 kB 查看哈希值)

上传于 CPython 3.10 manylinux: glibc 2.17+ ARM64

regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (697.5 kB 查看哈希值)

上传于 CPython 3.10 manylinux: glibc 2.12+ x86-64 manylinux: glibc 2.5+ x86-64

regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (772.3 kB 查看哈希值)

上传于 CPython 3.10 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl (284.6 kB 查看哈希值)

上传于 CPython 3.10 macOS 11.0+ ARM64

regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl (287.4 kB 查看哈希值)

上传于 CPython 3.10 macOS 10.9+ x86-64

regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl (482.5 kB 查看哈希值)

上传于 CPython 3.10 macOS 10.9+ universal2 (ARM64, x86-64)

regex-2024.9.11-cp39-cp39-win_amd64.whl (274.1 kB 查看哈希值)

上传于 CPython 3.9 Windows x86-64

regex-2024.9.11-cp39-cp39-win32.whl (261.7 kB 查看哈希值)

上传于 CPython 3.9 Windows x86

regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl (773.4 kB 查看哈希值)

上传于 CPython 3.9 musllinux: musl 1.2+ x86-64

regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl (844.9 kB 查看哈希值)

上传于 CPython 3.9 musllinux: musl 1.2+ s390x

regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl (845.0 kB 查看哈希值)

上传于 CPython 3.9 musllinux: musl 1.2+ ppc64le

regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl (776.9 kB 查看哈希值)

上传于 CPython 3.9 musllinux: musl 1.2+ i686

regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl (768.7 kB 查看哈希值)

上传于 CPython 3.9 musllinux: musl 1.2+ ARM64

regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (782.0 kB 查看哈希值)

上传于 CPython 3.9 manylinux: glibc 2.17+ x86-64

regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl (809.3 kB 查看哈希值)

上传于 CPython 3.9 manylinux: glibc 2.17+ s390x

regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (822.7 kB 查看哈希值)

上传于 CPython 3.9 manylinux: glibc 2.17+ ppc64le

regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (782.7 kB 查看哈希值)

上传于 CPython 3.9 manylinux: glibc 2.17+ ARM64

regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (697.0 kB 查看哈希值)

上传于 CPython 3.9 manylinux: glibc 2.12+ x86-64 manylinux: glibc 2.5+ x86-64

regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (771.9 kB 查看哈希值)

上传于 CPython 3.9 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl (284.6 kB 查看哈希值)

上传于 CPython 3.9 macOS 11.0+ ARM64

regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl (287.4 kB 查看哈希值)

上传于 CPython 3.9 macOS 10.9+ x86-64

regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl (482.5 kB 查看哈希值)

上传于 CPython 3.9 macOS 10.9+ universal2 (ARM64, x86-64)

regex-2024.9.11-cp38-cp38-win_amd64.whl (274.1 kB 查看哈希值)

上传于 CPython 3.8 Windows x86-64

regex-2024.9.11-cp38-cp38-win32.whl (261.7 kB 查看哈希值)

上传于 CPython 3.8 Windows x86

regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl (775.2 kB 查看哈希值)

上传于 CPython 3.8 musllinux: musl 1.2+ x86-64

regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl (846.4 kB 查看哈希值)

上传于 CPython 3.8 musllinux: musl 1.2+ s390x

regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl (846.1 kB 查看哈希值)

上传于 CPython 3.8 musllinux: musl 1.2+ ppc64le

regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl (777.2 kB 查看哈希值)

上传于 CPython 3.8 musllinux: musl 1.2+ i686

regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl (771.1 kB 查看哈希值)

上传于 CPython 3.8 musllinux: musl 1.2+ ARM64

regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (785.0 kB 查看哈希值)

上传于 CPython 3.8 manylinux: glibc 2.17+ x86-64

regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl (810.5 kB 查看哈希值)

上传于 CPython 3.8 manylinux: glibc 2.17+ s390x

regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (824.3 kB 查看哈希值)

上传于 CPython 3.8 manylinux: glibc 2.17+ ppc64le

regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (784.4 kB 查看哈希值)

上传于 CPython 3.8 manylinux: glibc 2.17+ ARM64

regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (702.5 kB 查看哈希值)

上传于 CPython 3.8 manylinux: glibc 2.12+ x86-64 manylinux: glibc 2.5+ x86-64

regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (774.3 kB 查看哈希值)

上传于 CPython 3.8 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl (284.6 kB 查看哈希值)

上传于 CPython 3.8 macOS 11.0+ ARM64

regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl (287.5 kB 查看哈希值)

上传于 CPython 3.8 macOS 10.9+ x86-64

regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl (482.6 kB 查看哈希值)

上传于 CPython 3.8 macOS 10.9+ universal2 (ARM64, x86-64)