使用python正则表达式从文件中的编号列表获取内容
我有以下行的文件: lines.txt使用python正则表达式从文件中的编号列表获取内容,python,regex,python-3.x,Python,Regex,Python 3.x,我有以下行的文件: lines.txt 1. robert smith 2. harry 3. john 我想得到如下数组: ["robert\nsmith","harry","john"] 我试过这样的方法: with open('lines.txt') as fh: m = [re.match(r"^\d+\.(.*)",line) for line in fh.readlines()] print(m) for i in m: print(
1. robert
smith
2. harry
3. john
我想得到如下数组:
["robert\nsmith","harry","john"]
我试过这样的方法:
with open('lines.txt') as fh:
m = [re.match(r"^\d+\.(.*)",line) for line in fh.readlines()]
print(m)
for i in m:
print(i.groups())
它的产出如下:
[<_sre.SRE_Match object; span=(0, 9), match='1. robert'>, None, <_sre.SRE_Match object; span=(0, 8), match='2. harry'>, <_sre.SRE_Match object; span=(0, 7), match='3. john'>]
(' robert',)
Traceback (most recent call last):
File "D:\workspaces\workspace6\PdfGenerator\PdfGenerator.py", line 5, in <module>
print(i.groups())
AttributeError: 'NoneType' object has no attribute 'groups'
[,无,]
(‘罗伯特’,)
回溯(最近一次呼叫最后一次):
文件“D:\workspaces\workspace6\PdfGenerator\PdfGenerator.py”,第5行,在
打印(i.组())
AttributeError:“非类型”对象没有属性“组”
看来我对这个问题的看法是非常错误的。您将如何解决此问题?您可以将文件读入内存并使用
r'(?ms)^\d+\.\s*(.*?)(?=^\d+\.|\Z)'
见
详细信息
-启用(?ms)
和re.MULTILINE
模式re.DOTALL
-行的开头^
-1+位\d+
-一个点\。
-0+空格\s*
-第1组(这是(.*)
在此返回的内容):任何0+字符,尽可能少re.findall
-直到(但不包括)第一次出现(?=^\d+\.\Z)
-行的开头,1+位和^\d+\。
-或|
-字符串结尾\Z
with open('lines.txt') as fh:
print(re.findall(r'(?ms)^\d+\.\s*(.*?)(?=^\d+\.|\Z)', fh.read()))
您可以将文件读入内存并使用
r'(?ms)^\d+\.\s*(.*?)(?=^\d+\.|\Z)'
见
详细信息
-启用(?ms)
和re.MULTILINE
模式re.DOTALL
-行的开头^
-1+位\d+
-一个点\。
-0+空格\s*
-第1组(这是(.*)
在此返回的内容):任何0+字符,尽可能少re.findall
-直到(但不包括)第一次出现(?=^\d+\.\Z)
-行的开头,1+位和^\d+\。
-或|
-字符串结尾\Z
with open('lines.txt') as fh:
print(re.findall(r'(?ms)^\d+\.\s*(.*?)(?=^\d+\.|\Z)', fh.read()))
使用
re.findall
查找从\d\.\s+
模式到下一个'\n\d'模式或直至结束的所有内容
>>> import re
>>> re.findall(r'\d+\.\s+(.*?(?=\n\d|$))', text, flags=re.DOTALL)
['robert\n smith', 'harry', 'john']
使用
re.findall
查找从\d\.\s+
模式到下一个'\n\d'模式或直至结束的所有内容
>>> import re
>>> re.findall(r'\d+\.\s+(.*?(?=\n\d|$))', text, flags=re.DOTALL)
['robert\n smith', 'harry', 'john']
您可以使用
re.split
正则表达式:
详情:
-换行符\n
-匹配范围为0到1次,如果存在“新行”,则匹配?
-匹配一个数字(+),匹配次数介于一次和无限次之间\d+
-Dot\。
-匹配零次和无限次之间的任何空白字符(等于\s*
)(*)[\r\n\t\f\v]
re.split(r'\n?\d+\.\s*', lines)[1:]
[1://code>删除第一项,因为它是空字符串
输出:
['robert\n smith', 'harry', 'john']
您可以使用re.split
正则表达式:
详情:
\n
-换行符
?
-匹配范围为0到1次,如果存在“新行”,则匹配
\d+
-匹配一个数字(+),匹配次数介于一次和无限次之间
\。
-Dot
\s*
-匹配零次和无限次之间的任何空白字符(等于[\r\n\t\f\v]
)(*)
Python代码:
re.split(r'\n?\d+\.\s*', lines)[1:]
[1://code>删除第一项,因为它是空字符串
输出:
['robert\n smith', 'harry', 'john']
我提出了一个解决方案,只收集名称,
在名字中间没有不必要的空格,
与其他一些解决方案相反
这个想法是:
- 保存元组列表(编号、名称和段),“正在复制”
前一行中的组号(如果当前行中没有)
线路。要保存的对由getPair函数准备
- 根据数字(第一个元素)对这些元组进行分组
- 使用分隔符\n连接每个组中的名称段
- 将这些连接的名称保存在结果列表中
使用列表理解可以在中编写程序
相当简洁的方式。见下文:
import re, itertools
def getPair(line):
global grp
nr, nameSegm = re.match(r'^(\d+\.)?\s+(\w+)$', line).groups()
if nr: # Number present
grp = nr
return grp, nameSegm
grp = '' # Group label (number)
with open('lines.txt') as fh:
lst = [getPair(line) for line in fh.readlines()]
res = ['\n'.join([t[1] for t in g])
for _, g in itertools.groupby(lst, lambda x: x[0])]
print(f"Result: {res}")
总而言之,这个程序比其他的稍长一点,但是很简单
只收集名称,不添加空格。我提出了一个解决方案,只收集名称,
在名字中间没有不必要的空格,
与其他一些解决方案相反
这个想法是:
- 保存元组列表(编号、名称和段),“正在复制”
前一行中的组号(如果当前行中没有)
线路。要保存的对由getPair函数准备
- 根据数字(第一个元素)对这些元组进行分组
- 使用分隔符\n连接每个组中的名称段
- 将这些连接的名称保存在结果列表中
使用列表理解可以在中编写程序
相当简洁的方式。见下文:
import re, itertools
def getPair(line):
global grp
nr, nameSegm = re.match(r'^(\d+\.)?\s+(\w+)$', line).groups()
if nr: # Number present
grp = nr
return grp, nameSegm
grp = '' # Group label (number)
with open('lines.txt') as fh:
lst = [getPair(line) for line in fh.readlines()]
res = ['\n'.join([t[1] for t in g])
for _, g in itertools.groupby(lst, lambda x: x[0])]
print(f"Result: {res}")
总而言之,这个程序比其他的稍长一点,但是很简单
仅名称,不带空格。如果print(i)
您将看到m[1]
是NoneType
,这就是您出现错误的原因。要验证这是否是错误,请尝试运行m[2::::
中的i,您将看到“组”是如何工作的。这并不能回答您的问题。如果您print(i)
,您将看到m[1]
是NoneType
,这就是您出现错误的原因。要验证这是否是错误,请尝试运行m[2::::
中的i,您将看到“组”是如何工作的。这并不能回答你的问题,你能解释一下吗?特别是\n?
和[1::
你能解释一下吗?尤其是\n?
和[1:][/code>更有效的变体是(?m)^\d+.\s*(.**:\n(?!\d+\.*))
更有效的变体是(?m)^\d+.\s*(.**:\n(?!\d+\.*)