【问题标题】:If string in one file matches string in another, print line and next line如果一个文件中的字符串与另一个文件中的字符串匹配,则打印行和下一行
【发布时间】:2019-05-14 21:08:19
【问题描述】:

我在完成一些我一直在处理的 python 代码时遇到了麻烦,如果有任何建议,我将不胜感激。我有两个文件:

文件1

>name1
>name3
>name4

文件2

>name1 blah blah
aaaaaaaaaaaaaaaaaaaaaaaaa
>name2 blah blah
cccccccaaaaaaaaaaaaaaaaaa
>name3 blah blah
aaaaaattttttttttaaaaaaaaa
>name4 blah blah
aaaaaattttttttttggggggggg
>name5 blah blah
aaaggggcccctttttggggggggg

file1 的每一行都包含一个在 file2 中也可以找到的字符串。对于 file1 的每一行,我想在 file2 中找到它匹配的行,然后打印该行和下一行。这是我想要的最终结果:

>name1 blah blah
aaaaaaaaaaaaaaaaaaaaaaaaa
>name3 blah blah
aaaaaattttttttttaaaaaaaaa
>name4 blah blah
aaaaaattttttttttggggggggg

我目前有以下代码:

nums=set()
    with open("file1.txt") as file1:
        for line in file1:
            nums.add(line.strip())

    with open("file2.txt") as file2, open("out.txt", "wt") 
    as outfile:
        for line in file2:
            if any(word in line for word in nums):
                outfile.write(line)

此代码目前包含两个问题:

  • file2 中与 file1 中的字符串匹配的任何子字符串都会打印到 outfile(使用此处的示例,如果 >name3 在集合 nums 中,则以 >name3 以及 >name31 和 >name367 开头的行将打印)

  • 我还没有弄清楚如何同时打印包含匹配项的行和下一行(也许这可以用 islice 完成?)

感谢您的建议!

【问题讨论】:

  • 请说明规格。两个文件中的名称是否保证顺序一致,或者您的第二个文件的顺序可能是name1 \n name5 \n name4?如果您想要完全匹配的名称,为什么要测试包含 (in) 而不是完全匹配?
  • 打印两行连续行的问题是您已经将file2 的控制权交给了迭代器;此构造不能满足您的需求。您需要更直接地阅读此内容。

标签: python python-3.x string


【解决方案1】:

第一期:

file2 中与 file1 中的字符串匹配的任何子字符串都将打印到 outfile(使用此处的示例,如果 >name3 在集合 nums 中,则将打印以 >name3 以及 >name31 和 >name367 开头的行)

这个问题可以通过两种方式解决。

  1. 只需添加空间。

    如果你确定你的“关键字”后面是空格,你可以添加只需添加空格

    示例:

    if any(word + " " in line for word in nums):
    
  2. 正则表达式。

    要解决这个问题,您可以使用正则表达式。您应该import re 并更改:

    if any(word in line for word in nums):
    

    收件人:

    if any(re.match(f"^{word}\\b", line) for word in nums):
    

    解释: ^ 表示行首,\b 是字边界。 Here 是正则表达式测试网站的链接。

第二期:

我还没有弄清楚如何打印包含匹配项的行和下一行(也许这可以用 islice 来完成?)

您使用 for line in file2: 逐行读取文件来遍历文件。如果要打印下一行,可以使用几种方法。

  1. 布尔标志。

    要实现这一点,您应该在循环之前声明布尔值并将其设置为False。如果此变量为True,则应在循环内部将行写入outfile,并将其更改回False。您应该在当前条件下将True 设置为该变量。

    示例:

    read_next = False
    for line in file2:
        if read_next:
            outfile.write(line)
            read_next = False
       if any(re.match(f"^{word}\\b", line) for word in nums):
            outfile.write(line)
            read_next = True
    
  2. 将循环从 for 更改为 while

    您可以使用readline() 方法(docs)手动迭代文件。

    示例:

    line = file2.readline()
    while line:
        line = line.strip()
        if any(re.match(f"^{word}\\b", line) for word in nums):
            outfile.write(line)
            line = file2.readline()
            if line:
                outfile.write(line)
            else: # if the end of file reached
                outfile.write("\n") # delete it in case if you don't need this
                break
        line = f.readline()
    

【讨论】:

  • 非常感谢@Olvin Roght,包括详细的解释。我最终使用您建议的正则表达式方法解决了问题一,并使用 while 循环解决了问题二。这得到了我想要的,只是在第一行打印后添加了一个新行字符。再次感谢!
【解决方案2】:
l=[]
# getting all the data from file and dividing them in two part and appending 
#them in a list
with open(r'C:\Users\user\RegForm.txt','r') as file:
    count =0 
    tmp=file.read().split('\n')
    for line in range(1,len(tmp),2):

        l.append([tmp[line-1],tmp[line]])


# getting all the value to search from file in a list
to_find=[]
with open(r'C:\Users\user\untitled0.txt','r') as file:
    for line in file:
        to_find.append(line.strip('\n'))

res =[]
# searching for file if they exist or not

for i in to_find:
    for j in l:
        if i in j[0]:
            print(j[0],j[1],sep='\n')
            break

"""
output

>name1 blah blah
aaaaaaaaaaaaaaaaaaaaaaaaa
>name3 blah blah
aaaaaattttttttttaaaaaaaaa
>name4 blah blah
aaaaaattttttttttggggggggg

"""

【讨论】:

  • 谢谢@prashant rana!
猜你喜欢
  • 1970-01-01
  • 2020-10-08
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-25
  • 1970-01-01
相关资源
最近更新 更多