我有一个格式如下的文件:
3 name1
2 name2
1 name3
数字和名称之间的空格可以是一个或多个空格,也可以是任意数量的标签。
我正在尝试找到一种方法来匹配此行与正则表达式,并在列表或元组中提取数字和名称。
我可以用几行来写这个,但我宁愿有一条干净的线,既可以识别标签和空白,也可以给我我的价值观。我没有成功。
编辑:我尝试使用re.search('^[\d]+[\s|\t]+.*', line)
来匹配任意数量的数字,空格或制表符以及任何内容。但这不起作用 - 大概是因为我没有告诉它为我提取什么。
答案 0 :(得分:5)
您需要做的就是在想要捕获的内容周围添加一些内容:
>>> line='1\t abc'
>>> re.search('^(\d+)\s+(.*)', line).groups()
('1', 'abc')
顺便提一下,请注意您使用的正则表达式以^
开头,该match
仅在行的开头匹配。因此,search
可用于代替>>> re.match('(\d+)\s+(.*)', line).groups()
('1', 'abc')
:
{{1}}
答案 1 :(得分:3)
您根本不需要正则表达式,str.split
如果您之间有1或21个空格并不重要:
lines="""3 name1
2 name2
1 name3"""
for line in lines.splitlines():
num, name = line.split()
print(num,name)
3 name1
2 name2
1 name3
在列表中:
print([line.split() for line in lines.splitlines()])
[['3', 'name1'], ['2', 'name2'], ['1', 'name3']]
在您自己的代码中用您的文件对象替换lines.splitlines()
。
使用正则表达式拆分空格并不是一个很好的方法:
In [13]: timeit re.search('^(\d+)\s+(.*)', line).groups()
1000000 loops, best of 3: 2.04 µs per loop
In [14]: timeit line.split()
1000000 loops, best of 3: 222 ns per loop
Out[15]: ('1', 'abc')
In [16]: line.split()
Out[16]: ['1', 'abc']
split在十分之一的时间内完全相同。
即使有两个以上的值,您也可以拆分并提取前两个:
lines="""3 name1 foo
2 name2 bar
1 name3 foobar """
print( [line.split(None, 2)[:2] for line in lines.splitlines()])
[['3', 'name1'], ['2', 'name2'], ['1', 'name3']]