我需要一些帮助打印文本文件中重复的姓氏(小写和大写应该相同) 程序不打印带数字的单词(例如,如果数字出现在姓或名中,则忽略整个姓名)
例如: 我的文本文件是:
Assaf Spanier, Assaf Din, Yo9ssi Levi, Yoram bibe9rman, David levi, Bibi Netanyahu, Amnon Levi, Ehud sPanier, Barak Spa7nier, Sara Neta4nyahu
输出应为:
^{pr2}$import re
def delete_numbers(line):
words = re.sub(r'\w*\d\w*', '', line).strip()
for t in re.split(r',', words):
if len(t.split()) == 1:
words = re.sub(t, '',words)
words = re.sub(',,', '', words)
return words
fname = input("Enter file name: ")
file = open(fname,"r")
for line in file.readlines():
words = delete_numbers(line)
first_name = re.findall(r"([a-zA-Z]+)\s",words)
for i in first_name:
print(i)
print("***")
a = ""
for t in re.split(r',', words):
a+= (", ".join(t.split()[1:])) + " "
好吧,既然你坚持用正则表达式来做,你应该努力在一个调用中完成,这样你就不会受到上下文切换的惩罚。最好的方法是编写一个模式来捕获不包含数字的所有名/姓,用逗号分隔,让正则表达式引擎捕获所有这些名字,然后迭代匹配项,最后将它们映射到字典,以便可以将它们拆分为姓氏=>;名字映射:
这会给你:
^{pr2}$另外,在
matches
中有完整的姓氏=>;名字匹配。在说到图案,让我们一块一块地分解:
当我们迭代匹配项时,
match
对象中会引用这两个捕获的组(名字和姓氏)。别紧张。在好的,首先让我们从一个侧面开始-用惯用的方式打开文件。使用
with
语句,它保证文件将被关闭。对于小脚本来说,这并不是什么大问题,但是如果您开始编写寿命更长的程序,由于错误关闭的文件而导致的内存泄漏可能会再次困扰您。因为您的文件将所有内容都放在一行:文件现在已关闭。这也鼓励您立即处理您的文件,而不是让它打开不必要地消耗资源。另外,假设你有多条线。不要使用
^{pr2}$for line in f.readlines()
,请使用以下构造:因为实际上不需要保存整个文件,只需要检查每一行,所以不要使用
readlines()
。如果您想保留一个行列表,比如lines = f.readlines()
,只使用readlines()
。在好的,最后,数据如下所示:
好的,如果您想在这里使用regex,我建议使用以下方法:
这里的模式},分别将模式锚定到文本的开头和结尾。另外,括号中创建了捕获组,我们将利用它。试着把这个复制粘贴到http://regexr.com/中,如果你还是不明白,就试试看。一个重要的注意事项是使用原始字符串,即
^(\D+)\s(\D+)$
使用非数字组,\D
(与\d
相反,数字组)和空白组\s
。此外,它还使用锚、^
和{r"this is a raw string"
与普通字符串"this is a normal string"
(注意r
)。这是因为Python字符串使用与regex模式相同的转义字符。这有助于保持你的理智。好的,最后,我建议使用分组习惯用法,加上dict
现在,我们的循环:
注意,我使用}将其设置为任何内容!在
.title
方法将我们所有的名字规范化为“Titlecase”。dict.setdefault
接受一个键作为它的第一个参数,如果这个键不存在,它将第二个参数设置为值,并返回它。所以,我要检查姓氏(在title case中)是否存在于grouper
dict中,如果不存在,则将其设置为空列表,[]
,然后{为了清晰起见,现在印刷精美:
这是一个非常有用的数据结构。例如,我们可以获取具有多个名字的所有姓氏:
所以,把它们放在一起:
注意,我假设顺序无关紧要,所以我使用了普通的
dict
。我的输出恰好是按正确的顺序排列的,因为在python3.6上,dict
是按顺序排列的!但不要依赖于此,因为它是实现细节,而不是保证。如果要保证订单,请使用collections.OrderedDict
。在相关问题 更多 >
编程相关推荐