从 Python 的 re 模块中获取正则表达式匹配和其余(none-匹配)
Get the regex match and the rest (none-match) from Python's re module
Python3 的 re
模块是否提供了一种内置方法来获取匹配项和其余的(none-匹配项)?
这是一个简单的例子:
>>> import re
>>> p = r'\d'
>>> s = '1a'
>>> re.findall(p, s)
['1']
我想要的结果是 ['1', 'a']
或 [['1'], ['a']]
或其他我可以区分 match 和 rest.
当然可以从原始字符串中减去生成的(匹配的)字符串以获得其余部分。但是有没有内置的方法呢?
我没有在此处设置 regex
标签,因为这个问题与 RegEx 本身的相关性较小,但与 Python 包的功能相关。
可能的解决方案如下:
import re
string = '1a'
re_pattern = r'^(\d+)(.*)'
result = re.findall(re_pattern, string)
print(result)
Returns 元组列表
[('1', 'a')]
或者如果你喜欢 return str 项目列表
result = [item for t in re.findall(re_pattern, string) for item in t]
print(result)
Returns
['1', 'a']
代码说明:
re_pattern = r'(\d+)(.*)'
正在寻找两组:第一组 (\d+)
表示一个或多个数字,第二组 (.*)
表示字符串的其余部分。
re.findall(re_pattern, string)
returns 元组列表,如 [('1', 'a')]
- 列表理解将元组列表转换为字符串项列表
不是,匹配不显示自己截断的数据
正则表达式为您提供的 Match 对象包含有关在哪里找到数据的信息,您可以用它提取它
import re
p = r'\d(?<=)'
s = '1a'
match = next(re.finditer(p, s))
# >>> match
# <re.Match object; span=(0, 1), match='1'>
head = match.string[:match.start()] # ""
tail = match.string[match.end():] # "a"
请注意 re.findall
不会为您提供 Match
-objects,您需要另一个函数来执行此操作,例如 re.finditer
。我在这里使用 next()
是因为它 returns 是一个迭代器而不是列表,您通常会将其转换为列表或对其进行循环。
另一种选择是直接在您的模式中创建这些组。
如果您对赛前和赛后都感兴趣:
import re
p = r'(^.*?)(\d)(.*$)'
s = '1a'
re.findall(p, s)
# [('', '1', 'a')]
但这不会在同一个字符串中为您提供多个结果,因为它们是重叠的,并且您不能在内置 re
库中使用 variable-with 回顾。
如果你只对匹配后的字符串感兴趣,那么你可以这样做
import re
p = r'(\d)(?=(.*))'
s = '1a'
re.findall(p, s)
# [('1', 'a')]
s = '1a2b'
re.findall(p, s)
# [('1', 'a2b'), ('2', 'b')]
您可以匹配所有内容并创建组以在重要部分与其余部分之间“拆分”:
>>> import re
>>> p = r'(\d+)(.*)'
>>> s = '12a\n34b\ncde'
>>> re.findall(p, s)
[('12', 'a'), ('34', 'b')]
Python3 的 re
模块是否提供了一种内置方法来获取匹配项和其余的(none-匹配项)?
这是一个简单的例子:
>>> import re
>>> p = r'\d'
>>> s = '1a'
>>> re.findall(p, s)
['1']
我想要的结果是 ['1', 'a']
或 [['1'], ['a']]
或其他我可以区分 match 和 rest.
当然可以从原始字符串中减去生成的(匹配的)字符串以获得其余部分。但是有没有内置的方法呢?
我没有在此处设置 regex
标签,因为这个问题与 RegEx 本身的相关性较小,但与 Python 包的功能相关。
可能的解决方案如下:
import re
string = '1a'
re_pattern = r'^(\d+)(.*)'
result = re.findall(re_pattern, string)
print(result)
Returns 元组列表
[('1', 'a')]
或者如果你喜欢 return str 项目列表
result = [item for t in re.findall(re_pattern, string) for item in t]
print(result)
Returns
['1', 'a']
代码说明:
re_pattern = r'(\d+)(.*)'
正在寻找两组:第一组(\d+)
表示一个或多个数字,第二组(.*)
表示字符串的其余部分。re.findall(re_pattern, string)
returns 元组列表,如[('1', 'a')]
- 列表理解将元组列表转换为字符串项列表
不是,匹配不显示自己截断的数据
正则表达式为您提供的 Match 对象包含有关在哪里找到数据的信息,您可以用它提取它
import re
p = r'\d(?<=)'
s = '1a'
match = next(re.finditer(p, s))
# >>> match
# <re.Match object; span=(0, 1), match='1'>
head = match.string[:match.start()] # ""
tail = match.string[match.end():] # "a"
请注意 re.findall
不会为您提供 Match
-objects,您需要另一个函数来执行此操作,例如 re.finditer
。我在这里使用 next()
是因为它 returns 是一个迭代器而不是列表,您通常会将其转换为列表或对其进行循环。
另一种选择是直接在您的模式中创建这些组。
如果您对赛前和赛后都感兴趣:
import re
p = r'(^.*?)(\d)(.*$)'
s = '1a'
re.findall(p, s)
# [('', '1', 'a')]
但这不会在同一个字符串中为您提供多个结果,因为它们是重叠的,并且您不能在内置 re
库中使用 variable-with 回顾。
如果你只对匹配后的字符串感兴趣,那么你可以这样做
import re
p = r'(\d)(?=(.*))'
s = '1a'
re.findall(p, s)
# [('1', 'a')]
s = '1a2b'
re.findall(p, s)
# [('1', 'a2b'), ('2', 'b')]
您可以匹配所有内容并创建组以在重要部分与其余部分之间“拆分”:
>>> import re
>>> p = r'(\d+)(.*)'
>>> s = '12a\n34b\ncde'
>>> re.findall(p, s)
[('12', 'a'), ('34', 'b')]