首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何提取文本文件中的行并查找重复项

如何提取文本文件中的行并查找重复项
EN

Stack Overflow用户
提问于 2017-12-01 06:03:07
回答 3查看 85关注 0票数 1

我有一个有很多行写的文本文件,在文本文件中有一个名为"@Testrun“的单词,将"@Testrun”作为起点和端点,同时考虑到这两个"@Testrun“之间的行为一个部分,这些文本可能有3到4个部分。我的问题是如何提取这些部分的线条,并在这些部分中找到重复的行:

我的文本文件如下:

代码语言:javascript
复制
@TestRun
    And user validate message on screen "Switch to paperless" 
    And user click on "Manage accounts" label 
    And user click link with label "View all online services" 
    And user waits for 10 seconds 
    Then page is successfully launched 
    And user click link with label "Go paperless for complete convenience" 
    Then page is successfully launched 
    And user validate message on screen "#EmailAddress" 
    And user clicks on the button "Confirm" 
    Then page is successfully launched 
    And user validate message on screen "#MessageValidate" 
    Then page is successfully launched 
    And user click on "menu open user preferences" label 
    And user clicks on the link "Statement and letter preferences" 
    Then page is successfully launched 
    And user validate "Switch to paperless" button is disabled 
    And user validate message on screen "Online only" 
    When user click on "Log out" label 
    Then page is successfully launched

@TestRun 
    And user click on link "Mobile site" 
    And user set text "#Surname" on textbox name "surname" 
    Then page is successfully launched 
    And user click on link "#Account" 
    Then page is successfully launched 
    And user verify message on screen "#Account" 
    And user verify message on screen "Manage statements" 
    And user verify message on screen "Step 1 of 3" 
    Then page is successfully launched 
    And user verify message on screen "Current format type"  
    And user verify message on screen "Online" 
    When user selects the radio button "Paper" 


@TestRun
Then user wait for page load
And user click on button "Continue to Online Banking"
Then user wait for page load
    And user click on "menu open user preferences" label 
    And user clicks on the link "Statement and letter preferences" 
    Then page is successfully launched 
    And page is successfully launched 
    And user waits for 10 seconds 
@TestRun 
    Then page is successfully launched 
    And user waits for 10 seconds 
    And user click checkbox "Telephone" 
    And user click checkbox "Post" 
    And user clicks on the button "Save" 
    Then page is successfully launched 

我尝试了以下代码,但这是行不通的:

代码语言:javascript
复制
with open('CustPref.txt') as input_data:
    for line in input_data:
        if line.strip() == '@TestRun ':  
            break
    for line in input_data: 
        if line.strip() == '@TestRun ':
            break
        print line

我得到输出,但这是完全不正确的。我只得到一行输出,不是expected.How,我解决了这个问题

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-12-01 06:25:55

使用more_itertools第三方库,我们可以在期望的目标之前拆分文本。

UPDATE:我们可以使用itertools.dropwhile在第一个目标之前删除行。

代码语言:javascript
复制
import itertools as it
import more_itertools as mit


with open("CustPref.txt", "r") as f:
    lines = f.readlines()

    pred = lambda x: x.startswith("@TestRun")      # trailing-space protection
    inv_pred = lambda x: not pred(x)

    lines = it.dropwhile(inv_pred, lines)          # optional
    chunks = list(mit.split_before(lines, pred))

print(chunks)

产出(缩写)

代码语言:javascript
复制
[['@TestRun\n',
  '    And user validate message on screen "Switch to paperless" \n',
  ...],
 ['@TestRun \n',
  '    And user click on link "Mobile site" \n',
  ...],
 ['@TestRun\n',
  'Then user wait for page load\n',
  ...],
 ...]
票数 0
EN

Stack Overflow用户

发布于 2017-12-01 06:22:42

你解决了两个问题:

  • 把它分解成相应的部分
  • 移除重复

分裂:

第一种选择

逐行解析文件:

代码语言:javascript
复制
parts = [] # all lines between 2 @TestRun's 
chunks = [] # all chunks of lines between 2 @TestRun's 

startNow = False # wait till first @TestRun before keeping anything

for line in Text(): # see definition for Text() below - it mimics your open('...')
    if line.strip() == '@TestRun':
        startNow = True
        if len(parts) > 0: # found a Testrun, if parts contains lines append to chunks
            chunks.append(parts)
            parts = []
    elif startNow == True: # check if first TestRun hit, if so append line to parts
        parts.append(line)


print(chunks) # done -> list of list of lines between chunks. 

第二种选择

不要将文本拆分成一行,以完整的文本形式阅读,并使用列表理解来拆分文本:

代码语言:javascript
复制
biggerChunks = [x.strip() for x in TextTT().split("@TestRun") ]
chunkified = [x.splitlines() for x in biggerChunks if len(x.strip()) > 0 ]

您首先在@TestRun上拆分,得到一个大文本块的列表,然后将每个文本块按行拆分。结果大致相同:[2@TestRun之间的所有行]

删除重复的(同时保持订单)

在这里得到了回答:how-do-you-remove-duplicates-from-a-list-in-whilst-preserving-order --这是一个SO链接,所以不会在这里再次反悔:)

Helpers Text()是打开的文件的替换,TestTT()是整个文本块:

代码语言:javascript
复制
def Text(): # instead of file open, returns list of lines
    return TextTT().splitlines() 

def TextTT(): # unsplit text
    return '''
@TestRun
    And user validate message on screen "Switch to paperless" 
    And user click on "Manage accounts" label 
    And user click link with label "View all online services" 
    And user waits for 10 seconds 
    Then page is successfully launched 
    And user click link with label "Go paperless for complete convenience" 
    Then page is successfully launched 
    And user validate message on screen "#EmailAddress" 
    And user clicks on the button "Confirm" 
    Then page is successfully launched 
    And user validate message on screen "#MessageValidate" 
    Then page is successfully launched 
    And user click on "menu open user preferences" label 
    And user clicks on the link "Statement and letter preferences" 
    Then page is successfully launched 
    And user validate "Switch to paperless" button is disabled 
    And user validate message on screen "Online only" 
    When user click on "Log out" label 
    Then page is successfully launched

@TestRun 
    And user click on link "Mobile site" 
    And user set text "#Surname" on textbox name "surname" 
    Then page is successfully launched 
    And user click on link "#Account" 
    Then page is successfully launched 
    And user verify message on screen "#Account" 
    And user verify message on screen "Manage statements" 
    And user verify message on screen "Step 1 of 3" 
    Then page is successfully launched 
    And user verify message on screen "Current format type"  
    And user verify message on screen "Online" 
    When user selects the radio button "Paper" 


@TestRun
Then user wait for page load
And user click on button "Continue to Online Banking"
Then user wait for page load
    And user click on "menu open user preferences" label 
    And user clicks on the link "Statement and letter preferences" 
    Then page is successfully launched 
    And page is successfully launched 
    And user waits for 10 seconds 
@TestRun 
    Then page is successfully launched 
    And user waits for 10 seconds 
    And user click checkbox "Telephone" 
    And user click checkbox "Post" 
    And user clicks on the button "Save" 
    Then page is successfully launched 
'''

有关解释,请参见注释--您可以使用f.e。如果需要,可以使用itertools.chain来重新组合内线

票数 0
EN

Stack Overflow用户

发布于 2017-12-01 06:31:50

一个简单的方法是记住你已经看到的线条。您可以将它们收集到列表中,但是使用字典或集合会更有效。

一次读一行。如果这行(不是一个新的TestRun头)已经见过,就不要打印它。如果它是一个TestRun头,忘记您已经看到的。把循环中的所有东西打印出来。从下一行开始。

代码语言:javascript
复制
with open('CustPref.txt') as input_data:
    seen = set()
    for line in input_data:
        # trim trailing newline
        line = line.rstrip('\n')
        if line == '@TestRun ':   # really sure about the trailing space?
            seen = set()          # who am I? what day is it?
        elif line in seen:
            # skip the rest of the for loop and start over
            continue
        else:
            seen.add(line)
        print(line)

从编程上讲,按照这个顺序检查“它是否是@TestRun,如果已经看到,则添加到seen”,这样您就不必检查它是否是@TestRun两次。我想保持更自然的秩序,在上面的论述,使它更简单。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47587497

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档