如何删除我的 python 脚本中的重复项?
How to remove duplicates in my python script?
我使用正则表达式搜索从文本文件(搜索“.js”)中过滤出一些结果,这给了我大约 16 个结果,其中一些是重复的。我想从该输出中删除重复项并将其打印到控制台或将其重定向到文件中。我尝试使用集合和 dictionary.fromkeys 但没有成功!这是我目前所拥有的,在此先感谢您:
#!/usr/bin/python
import re
import sys
pattern = re.compile("[^/]*\.js")
for i, line in enumerate(open('access_log.txt')):
for match in re.findall(pattern, line):
x = str(match)
print x
为什么 set
不起作用,哪里出了问题?你试过如下吗?
import re
import sys
pattern = re.compile("[^/]*\.js")
results = set()
for i, line in enumerate(open('access_log.txt')):
for match in re.findall(pattern, line):
results.add(str(match))
使用集消除重复:
#!/usr/bin/python
import re
pattern = re.compile("[^/]*\.js")
matches = set()
with open('access_log.txt') as f:
for line in f:
for match in re.findall(pattern, line):
#x = str(match) # or just use match
if match not in in matches:
print match
matches.add(match)
但我质疑你的正则表达式:
你在每行做一个findall
,这表明每行可能有多个"hits",例如:
file1.js file2.js file3.js
但是在你的正则表达式中:
[^/]*\.js
[^/]*
正在进行贪婪匹配,并且 return 只会匹配一个,即完整的行。
如果您将匹配设置为非贪婪匹配,即 [^/]*?
,那么您将获得 3 个匹配项:
'file1.js'
' file2.js'
' file3.js'
但这突出了另一个潜在问题。对于这些特殊情况,您真的想要在第二场和第三场比赛中使用这些空间吗?也许在 /abc/ def.js
的情况下,您会保留 /abc/
.
之后的前导空白
所以我建议:
#!/usr/bin/python
import re
pattern = re.compile("""
(?x) # verbose mode
(?: # first alternative:
(?<=/) # positive lookbehind assertion: preceded by '/'
[^/]*? # matches non-greedily 0 or more non-'/'
| # second alternative
(?<!/) # negative lookbehind assertion: not preceded by '/'
[^/\s]*? # matches non-greedily 0 or more non-'/' or non-whitespace
)
\.js # matches '.js'
""")
matches = set()
with open('access_log.txt') as f:
for line in f:
for match in pattern.findall(line):
if match not in matches:
print match
matches.add(match)
如果文件名不能有任何空格,那么就使用:
pattern = re.compile("[^\s/]*?\.js")
我使用正则表达式搜索从文本文件(搜索“.js”)中过滤出一些结果,这给了我大约 16 个结果,其中一些是重复的。我想从该输出中删除重复项并将其打印到控制台或将其重定向到文件中。我尝试使用集合和 dictionary.fromkeys 但没有成功!这是我目前所拥有的,在此先感谢您:
#!/usr/bin/python
import re
import sys
pattern = re.compile("[^/]*\.js")
for i, line in enumerate(open('access_log.txt')):
for match in re.findall(pattern, line):
x = str(match)
print x
为什么 set
不起作用,哪里出了问题?你试过如下吗?
import re
import sys
pattern = re.compile("[^/]*\.js")
results = set()
for i, line in enumerate(open('access_log.txt')):
for match in re.findall(pattern, line):
results.add(str(match))
使用集消除重复:
#!/usr/bin/python
import re
pattern = re.compile("[^/]*\.js")
matches = set()
with open('access_log.txt') as f:
for line in f:
for match in re.findall(pattern, line):
#x = str(match) # or just use match
if match not in in matches:
print match
matches.add(match)
但我质疑你的正则表达式:
你在每行做一个findall
,这表明每行可能有多个"hits",例如:
file1.js file2.js file3.js
但是在你的正则表达式中:
[^/]*\.js
[^/]*
正在进行贪婪匹配,并且 return 只会匹配一个,即完整的行。
如果您将匹配设置为非贪婪匹配,即 [^/]*?
,那么您将获得 3 个匹配项:
'file1.js'
' file2.js'
' file3.js'
但这突出了另一个潜在问题。对于这些特殊情况,您真的想要在第二场和第三场比赛中使用这些空间吗?也许在 /abc/ def.js
的情况下,您会保留 /abc/
.
所以我建议:
#!/usr/bin/python
import re
pattern = re.compile("""
(?x) # verbose mode
(?: # first alternative:
(?<=/) # positive lookbehind assertion: preceded by '/'
[^/]*? # matches non-greedily 0 or more non-'/'
| # second alternative
(?<!/) # negative lookbehind assertion: not preceded by '/'
[^/\s]*? # matches non-greedily 0 or more non-'/' or non-whitespace
)
\.js # matches '.js'
""")
matches = set()
with open('access_log.txt') as f:
for line in f:
for match in pattern.findall(line):
if match not in matches:
print match
matches.add(match)
如果文件名不能有任何空格,那么就使用:
pattern = re.compile("[^\s/]*?\.js")