【问题标题】:How to extract specific data from a string?如何从字符串中提取特定数据?
【发布时间】:2019-05-20 21:43:50
【问题描述】:

我有一个要解析的文本文档。我希望能够获得“@5c00\n”和“@ffd2\n”之间以及“@ffd2\n”和“@”之间的字符串

@5c00
81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 
B1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 
@ffd2
14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 00 5C CF 0C 
@
q

我尝试使用正则表达式,但这似乎给了我 ['','']。

file = open("app_blink.txt","r") #app_blink.txt being the string above
contents = file.read()
data = re.findall('\n(.*)@',contents,re.M)

我希望得到:

data
['81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 \nB1 13 38 01 32 D0 10 00..
 FD 3F 03 43 00 00 00 02','14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C..
 \n14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C \n14 5C 14 5C 14 5C 14..
 5C 14 5C 14 5C 00 5C CF 0C \n']

但实际上得到了:

data
['','']

【问题讨论】:

    标签: arrays regex python-3.x string split


    【解决方案1】:

    你很亲密。您需要 re.DOTALL 标志,以及非贪婪匹配:

    contents = '''\
    @5c00
    81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 
    B1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 
    @ffd2
    14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
    14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
    14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 00 5C CF 0C 
    @
    q
    '''
    
    import re
    for x in re.findall(r'\n(.*?)@',contents,re.DOTALL):
        print(x)
    

    输出:

    81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 
    B1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 
    
    14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
    14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
    14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 00 5C CF 0C 
    

    【讨论】:

      【解决方案2】:

      这听起来像是正则表达式的工作!

      \@[^\n]*\n([^\@]*)\n(?=\@)
      

      这个正则表达式将匹配:

      • 首先,一个文字 @ 符号
      • 然后,任何一行字符,以换行符结尾
      • 然后,它可以找到不包括@ 的所有内容:这部分被保存到组#1 中
      • 然后,换行符结束所有内容
      • 最后,仅当下一个字符是 @ 时才接受(但不要使用该字符)

      举个例子:

      >>> re.search(r'\@[^\n]*\n([^\@]*)\n(?=\@)', your_string).group(1)
      '81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 \nB1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 '
      

      所以要列出重要的东西:

      >>> [m.group(1) for m in re.finditer(r'\@[^\n]*\n([^\@]*)\n(?=\@)', your_string)]
      ['81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 \nB1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 ', '14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C \n14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C \n14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 00 5C CF 0C ']
      

      或者,为了更简单的答案:

      re.split(r'\@[^\n]*\n', your_string)
      

      只要找到以@ 开头的行,就拆分字符串。

      【讨论】:

      • 哇!感谢您的帮助!非常感谢您花时间解释您的正则表达式
      【解决方案3】:

      检查这个正则表达式:

      data = re.findall('^[\d \w]{2,}$',contents,re.M)
      

      它只是采用具有十六进制数字的行。

      【讨论】:

        【解决方案4】:

        这个正则表达式应该可以工作Tryit

        import re
        
        regex = r"^[^\@].*"
        
        test_str = ("@5c00\n81 00 00\n76 20 11\n@ffd2\n")
        
        matches = re.finditer(regex, test_str, re.MULTILINE)
        
        for matchNum, match in enumerate(matches, start=1):
        
            print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))
        
            for groupNum in range(0, len(match.groups())):
                groupNum = groupNum + 1
        
                print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum)))
        

        注意:为了兼容 Python 2.7,请使用 ur"" 作为正则表达式的前缀,使用 u"" 作为测试字符串和替换的前缀。

        【讨论】:

          【解决方案5】:

          在这里,我们可能不想使用正则表达式,因为它可能会变得有点贵。也许字符串拆分会很好。比如我们可以用@分割。

          示例

          # coding=utf8
          # the above tag defines encoding for this document and is for Python 2.x compatibility
          
          import re
          
          test_str = '''
          @bb00
          81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 
          B1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02
          @5c00
          81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 
          B1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 
          @ffd2
          14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
          14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
          14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 00 5C CF 0C 
          @
          81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 
          B1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 
          
          '''
          
          split_str = test_str.split('@')
          data=[]
          for matches in split_str:
            if (matches[:4] == '5c00' or matches[:4] == 'ffd2'):
              data.append(matches[5:])
          
          
          print(data)
          

          输出

          ['81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 \nB1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 \n', '14 5C 14 5C 14 5C 14 5℃ 14 5℃ 14 5C 14 5C 14 5C \n14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C \n14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 00 5C CF 0C \n']

          【讨论】:

            猜你喜欢
            • 2020-07-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-09-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多