【问题标题】:Using regular expresions to extract part of a string in a list使用正则表达式提取列表中的部分字符串
【发布时间】:2019-03-08 10:43:18
【问题描述】:

如标题所述,我正在尝试使用正则表达式来提取字符串的一部分,即列表中的一部分。 该列表包含多个字符串,如下所示:

 "[Decoded(data=b'FF01664817', rect=Rect(left=132, top=207, width=171,height=1))]", 
 "[Decoded(data=b'FF01664833', rect=Rect(left=227, top=128, width=-6, height=175))]"

对于一些上下文,字符串是我使用cv2 解码的数据矩阵。我想要的是得到‘ ’(数据矩阵内容)之间的部分,而不是其余部分。

我的方法是这样的:

Data=[re.match(r"\'.*'\)",x[0]) for x in Data]

但是当我打印我的数据时,它只为列表中的每个字符串返回"Null"

其余代码

import cv2
import numpy as np
import ctypes  
from pylibdmtx.pylibdmtx import decode
import csv
import re

img = cv2.imread('C:/Users/ML/Desktop/DataMatrix/Test2.jpg')
img2 = img

height, width, channels = img.shape

CROP_W_SIZE  = 8 
CROP_H_SIZE = 6

Data = []

for ih in range(CROP_H_SIZE ):
    for iw in range(CROP_W_SIZE ):

        x = int(width / CROP_W_SIZE * iw)
        y = int(height / CROP_H_SIZE * ih)
        h = int((height / CROP_H_SIZE))
        w = int((width / CROP_W_SIZE ))
       # print(x,y,h,w)

        img = img[y:y+h, x:x+w]

        Name = str(time.time()) 
        cv2.imwrite("C:/Users/ML/Desktop/DataMatrix/CROP/" + 'Crop' + str(x+y) +  ".jpg",img)
        img = img2

        Data.append(str(decode(cv2.imread('C:/Users/ML/Desktop/DataMatrix/CROP/'+ 'Crop' + str(x+y) +'.jpg'))))

Data=[re.match(r"\'.*'\)",x[0]) for x in Data]
print(Data)

【问题讨论】:

  • 你想得到什么输出?
  • 该数据看起来像 python 对象的字符串表示形式,这就引出了一个问题,为什么您要尝试解析字符串而不是直接使用这些对象?
  • 我认为您的做法是错误的...如果您可以再次运行生成该输出的程序,则应将其更改为以机器可读格式(如 JSON)输出文件试图解析那些代表。
  • FF01664817, FF01664833
  • 如何直接使用对象?

标签: python regex


【解决方案1】:

这非常脆弱,可能会被看起来不像你的数据的数据严重破坏,但是......

import re


def parse_key_value(s):
    return {
        m.group(1): m.group(2) or m.group(3)
        for m in re.finditer(
            r"([a-z]+)=(?:b\'(.+?)\'|(-?\d+?))[,)]", s
        )
    }


for x in [
    "[Decoded(data=b'FF01664817', rect=Rect(left=132, top=207, width=171, height=1))]",
    "[Decoded(data=b'FF01664833', rect=Rect(left=227, top=128, width=-6, height=175))]",
]:
    print(parse_key_value(x))

输出

{'data': 'FF01664817', 'left': '132', 'top': '207', 'width': '171', 'height': '1'}
{'data': 'FF01664833', 'left': '227', 'top': '128', 'width': '-6', 'height': '175'}

【讨论】:

    【解决方案2】:

    使用search() 代替match()。最后一个函数仅在匹配位于字符串开头时才有效:

    import re
    
    s = "[Decoded(data=b'FF01664817', rect=Rect(left=132, top=207, width=171, height=1))]"
    
    print(re.search(r"'(.+?)'", s).group())
    # FF01664817
    

    【讨论】:

      【解决方案3】:

      尝试摆脱 str 并拥有

      Data.extend(decode(cv2.imread('C:/Users/ML/Desktop/DataMatrix/CROP/'+ 'Crop' + str(x+y) +'.jpg')))
      

      在循环中。

      然后尝试做:

      Data = [x.data for x in Data]
      

      或者在循环中你可以直接做:

      Data.extend(i.data for i in decode(cv2.imread(
          'C:/Users/ML/Desktop/DataMatrix/CROP/'+ 'Crop' + str(x+y) +'.jpg'
      )))
      

      然后Data 将包含您需要的内容。

      Decoded 是一个具有datarect 属性的命名元组,因此您可以直接访问.data 并获得所需的内容(您可以查看其定义here)。

      使用正则表达式来提取你需要的东西是缓慢的、不可靠的并且非常笨拙。

      通过直接对对象进行操作,您可以更加灵活地编写列表以及传递它们。

      您还保留了属性的原始类型。

      【讨论】:

      • hmm 试过这个方法,但总是报错:'list' object has no attribute 'data'
      • 啊,是的,对不起,decode 返回一个列表,你能看到我的编辑吗?
      【解决方案4】:

      regex match() 只匹配字符串的开头。 regex search() 实际上搜索所有字符串。

      import re
      list = ["[Decoded(data=b'FF01664817', rect=Rect(left=132, top=207, width=171, height=1))]",
              "[Decoded(data=b'FF01664833', rect=Rect(left=227, top=128, width=-6, height=175))]"]
      data = [re.search(r''''.*''', x) for x in list]
      

      输出:

      [<_sre.SRE_Match object; span=(15, 80), match="'FF01664817', rect=Rect(left=132, top=207, width=>, <_sre.SRE_Match object; span=(15, 81), match="'FF01664833', rect=Rect(left=227, top=128, width=>]
      

      使用 .group() 方法获取匹配结果。

      # FF01664817,FF01664833
      

      【讨论】:

        【解决方案5】:

        我想你正在寻找re.searchre.findall

        import re
        
        v = ["[Decoded(data=b'FF01664817', rect=Rect(left=132, top=207, width=171, \
                height=1))]", "[Decoded(data=b'FF01664833', rect=Rect(left=227, \
                top=128, width=-6, height=175))]"]
        se = [re.search(r"b'(.+)'", x).group(1) for x in v]
        fa = [re.findall(r"b'(.+)'", x) for x in v]
        print(se)
        print(fa)
        

        输出:

        ['FF01664817', 'FF01664833']
        [['FF01664817'], ['FF01664833']]

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-07-12
          • 1970-01-01
          • 2021-12-30
          • 1970-01-01
          • 2017-12-08
          • 2015-12-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多