Python 在字符串中查找重复的单词并使用re打印它们
我需要一些在文本文件中打印重复姓氏的帮助(小写和大写应该相同) 程序不打印带有数字的单词(即,如果数字出现在姓或名中,则忽略全名) 例如: 我的文本文件是:Python 在字符串中查找重复的单词并使用re打印它们,python,regex,python-3.x,Python,Regex,Python 3.x,我需要一些在文本文件中打印重复姓氏的帮助(小写和大写应该相同) 程序不打印带有数字的单词(即,如果数字出现在姓或名中,则忽略全名) 例如: 我的文本文件是: Assaf Spanier, Assaf Din, Yo9ssi Levi, Yoram bibe9rman, David levi, Bibi Netanyahu, Amnon Levi, Ehud sPanier, Barak Spa7nier, Sara Neta4nyahu 输出应为: Assaf Assaf David B
Assaf Spanier, Assaf Din, Yo9ssi Levi, Yoram bibe9rman, David levi, Bibi Netanyahu, Amnon Levi, Ehud sPanier, Barak Spa7nier, Sara Neta4nyahu
输出应为:
Assaf
Assaf
David
Bibi
Amnon
Ehud
========
Spanier
Levi
重新导入
def delete_编号(第行):
words=re.sub(r'\w*\d\w*','',第行).strip()
对于拆分中的t(r’,’,单词):
如果len(t.split())==1:
词语=子条款(t,,,词语)
words=re.sub(“,”,“,”,words)
回话
fname=input(“输入文件名:”)
文件=打开(fname,“r”)
对于文件.readlines()中的行:
单词=删除数字(行)
first_name=re.findall(r“([a-zA-Z]+)\s”,单词)
对于我的名字:
印刷品(一)
打印(“***”)
a=“”
对于拆分中的t(r’,’,单词):
a++=(“,”.join(t.split()[1:])+”
好的,首先让我们从一个侧边开始-以惯用的方式打开文件。使用with
语句,该语句保证文件将被关闭。对于小脚本来说,这没什么大不了的,但如果您开始编写寿命更长的程序,由于错误关闭文件而导致的内存泄漏可能会再次困扰您。由于您的文件在一行中包含所有内容:
with open(fname) as f:
data = f.read()
文件现在已关闭。这也鼓励您立即处理您的文件,而不是让它处于打开状态,不必要地消耗资源。另一方面,假设您有多行。不要对f.readlines()中的行使用,
,而是使用以下结构:
with open(fname) as f:
for line in f:
do_stuff(line)
因为实际上不需要保存整个文件,只需要检查每一行,所以不要使用readlines()
。如果要保留行列表,请仅使用readlines()
,例如lines=f.readlines()
好的,最后,数据将如下所示:
>>> print(data)
Assaf Spanier, Assaf Din, Yo9ssi Levi, Yoram bibe9rman, David levi, Bibi Netanyahu, Amnon Levi, Ehud sPanier, Barak Spa7nier, Sara Neta4nyahu
好的,如果您想在这里使用正则表达式,我建议使用以下方法:
>>> names_regex = re.compile(r"^(\D+)\s(\D+)$")
这里的模式,^(\D+)\s(\D+)$
使用非数字组,\D
(与\D
相反的数字组)和空白组,\s
。此外,它还使用锚定(^
和$
)将模式分别锚定到文本的开头和结尾。此外,括号还创建了捕获组,我们将利用它们。如果你还不明白,试着把它复制粘贴到你的电脑里,然后玩一玩。一个重要的注意事项是,使用原始字符串,即r“这是原始字符串”
与普通字符串相比,“这是普通字符串”
(注意r
)。这是因为Python字符串使用了一些与正则表达式模式相同的转义字符。这将有助于保持你的理智。好的,最后,我建议使用分组习惯用法,使用dict
>>> grouper = {}
现在,我们的循环:
>>> for fullname in data.split(','):
... match = names_regex.search(fullname.strip())
... if match:
... first, last = match.group(1), match.group(2)
... grouper.setdefault(last.title(), []).append(first.title())
...
注意,我使用.title
方法将我们所有的名字规范化为“Titlecase”dict.setdefault
将一个键作为第一个参数,如果该键不存在,则将第二个参数设置为值,并返回该值。因此,我正在检查grouper
dict中是否存在姓,如果不存在,则将其设置为空列表,[]
,然后将附加到任何存在的内容中
为了清晰起见,现在进行漂亮的打印:
>>> from pprint import pprint
>>> pprint(grouper)
{'Din': ['Assaf'],
'Levi': ['David', 'Amnon'],
'Netanyahu': ['Bibi'],
'Spanier': ['Assaf', 'Ehud']}
这是一个非常有用的数据结构。例如,我们可以用一个以上的名字获取所有姓氏:
>>> for last, firsts in grouper.items():
... if len(firsts) > 1:
... print(last)
...
Spanier
Levi
因此,把所有这些放在一起:
>>> grouper = {}
>>> names_regex = re.compile(r"^(\D+)\s(\D+)$")
>>> for fullname in data.split(','):
... match = names_regex.search(fullname.strip())
... if match:
... first, last = match.group(1), match.group(2)
... first, last = first.title(), last.title()
... print(first)
... grouper.setdefault(last, []).append(first)
...
Assaf
Assaf
David
Bibi
Amnon
Ehud
>>> for last, firsts in grouper.items():
... if len(firsts) > 1:
... print(last)
...
Spanier
Levi
注意,我假设顺序无关紧要,所以我使用了一个普通的dict
。我的输出恰好顺序正确,因为在Python3.6上,dict
s是有序的!但不要依赖于此,因为这是一个实现细节,而不是保证。如果您想保证订单,请使用collections.OrderedDict。好的,首先让我们从一个侧边开始-以惯用的方式打开文件。使用with
语句,该语句保证文件将被关闭。对于小脚本来说,这没什么大不了的,但如果您开始编写寿命更长的程序,由于错误关闭文件而导致的内存泄漏可能会再次困扰您。由于您的文件在一行中包含所有内容:
with open(fname) as f:
data = f.read()
文件现在已关闭。这也鼓励您立即处理您的文件,而不是让它处于打开状态,不必要地消耗资源。另一方面,假设您有多行。不要对f.readlines()中的行使用,
,而是使用以下结构:
with open(fname) as f:
for line in f:
do_stuff(line)
因为实际上不需要保存整个文件,只需要检查每一行,所以不要使用readlines()
。如果要保留行列表,请仅使用readlines()
,例如lines=f.readlines()
好的,最后,数据将如下所示:
>>> print(data)
Assaf Spanier, Assaf Din, Yo9ssi Levi, Yoram bibe9rman, David levi, Bibi Netanyahu, Amnon Levi, Ehud sPanier, Barak Spa7nier, Sara Neta4nyahu
好的,如果您想在这里使用正则表达式,我建议使用以下方法:
>>> names_regex = re.compile(r"^(\D+)\s(\D+)$")
这里的模式,^(\D+)\s(\D+)$
使用非数字组,\D
(与\D
相反的数字组)和空白组,\s
。此外,它还使用锚定(^
和$
)将模式分别锚定到文本的开头和结尾。此外,括号还创建了捕获组,我们将利用它们。如果你还不明白,试着把它复制粘贴到你的电脑里,然后玩一玩。一个重要的注意事项是,使用原始字符串,即r“这是原始字符串”
与普通字符串相比,“这是普通字符串”
(注意r
)。这是因为Python字符串使用了一些与正则表达式模式相同的转义字符。这将有助于保持你的理智。好的,最后,我建议使用分组习惯用法,使用dict
>>> grouper = {}
现在,我们的循环:
>>> for fullname in data.split(','):
... match = names_regex.search(fullname.strip())
... if match:
... first, last = match.group(1), match.group(2)
... grouper.setdefault(last.title(), []).append(first.title())
...
注意,我使用.title
方法将我们所有的名字规范化为“Titlecase”dict.setdefault
将一个键作为其第一个参数,如果该键不存在,则设置