Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在字符串中查找重复的单词并使用re打印它们_Python_Regex_Python 3.x - Fatal编程技术网

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
将一个键作为其第一个参数,如果该键不存在,则设置