liyuping-fisher 发表于 2023-3-23 15:52:17

正则匹配问题


ctestRatio       = 30;#180/10000 = 1.8%
如上是文件中的数据,我要通过cPanelSpreadRatio在文件中搜索匹配=和;之间的30这个值,可以用r'(?<==)(?=;)匹配吗,小白不会弄,这里用=做了分隔符,但是=后面值的后面是分号,分号后面太杂乱了,所以想用=和;之间的数据作为value
部分代码如下

                def read_file(file_path):
                  with open(file_path, 'rb') as f:
                        # 检测文件编码
                        result = chardet.detect(f.read())
                        f.seek(0)
                        return f.readlines()
            for file_path in all_files:
                if file_path.endswith('.ini'):
                  #print("打印文件:" + file_path)
                  f = read_file(file_path)
                  # 遍历需要抓取的key并输出对应的值
                  try:
                        for each_line in f:
                            for key in PQ_keys:
                              if key in each_line.decode('utf-8'):
                                    key, value = each_line.decode('utf-8').strip().split('=')
                                    print('{}:{}={}'.format(file_path, key, value))
                  except UnicodeDecodeError:
                        print('解码文件 {} 时发生错误'.format(file_path))

isdkz 发表于 2023-3-23 15:59:41

本帖最后由 isdkz 于 2023-3-23 16:05 编辑

正则表达式可以用 ctestRatio\s*=\s*(\S+);

示例代码:

import re

pattern= re.compile(r"ctestRatio\s*=\s*(\S+);")
s = "ctestRatio       = 30;#180/10000 = 1.8%"
lst = pattern.findall(s)
print(lst)

ouyunfu 发表于 2023-3-23 16:33:04

可以尝试一下这上代码:import re

ctestRatio = 30
pattern = r'=(\d+);'
for each_line in f:
    for key in PQ_keys:
      if key in each_line.decode('utf-8'):
            match = re.search(pattern, each_line.decode('utf-8'))
            if match:
                value = int(match.group(1))
                if value == ctestRatio:
                  print('{}:{}={}'.format(file_path, key, value))

首先定义了一个变量ctestRatio,它存储了我们要查找的值。然后,使用了re.search()函数来搜索每一行中匹配正则表达式r'=(\d+);'的内容。这个正则表达式表示,我们要查找一个以=开头、以;结尾的子字符串,并将其中的数字捕获到一个分组中。如果找到了这样的子字符串,将其捕获的数字转换成整数,并与ctestRatio比较。如果相等,则打印文件路径、键和值。

liyuping-fisher 发表于 2023-3-23 16:51:52

isdkz 发表于 2023-3-23 15:59
正则表达式可以用 ctestRatio\s*=\s*(\S+);

示例代码:

没太明白,ctestRatio这个是个变量,也就是代码中的key,因为我有很多key

liyuping-fisher 发表于 2023-3-23 16:54:12

ouyunfu 发表于 2023-3-23 16:33
可以尝试一下这上代码:
首先定义了一个变量ctestRatio,它存储了我们要查找的值。然后,使用了re.search( ...

代码中的key本身是个变量,这个变量的值是“ctestRataio”,也可能是其实,我是通过这个key的变量在文件中找到"ctestRatio       = 30;#180/10000 = 1.8%"这一行(只是一个key搜索出来的结果),在取其=和;之间的数据

isdkz 发表于 2023-3-23 16:54:17

liyuping-fisher 发表于 2023-3-23 16:51
没太明白,ctestRatio这个是个变量,也就是代码中的key,因为我有很多key

也就是你要匹配每一个等号和分号之间的内容作为 value,前面的内容作为 key?

liyuping-fisher 发表于 2023-3-23 16:55:45

isdkz 发表于 2023-3-23 16:54
也就是你要匹配每一个等号和分号之间的内容作为 value,前面的内容作为 key?

是的是的,用key这个变量遍历每一行,然后每一行的数据大概就是“"ctestRatio       = 30;#180/10000 = 1.8%"这样的,我要等号前面的就是key,=和;之间的是我要提起的value

isdkz 发表于 2023-3-23 17:03:06

liyuping-fisher 发表于 2023-3-23 16:55
是的是的,用key这个变量遍历每一行,然后每一行的数据大概就是“"ctestRatio       = 30;#180/10000 = 1 ...

看看这是不是你想要的效果

参考代码:
import re

pattern= re.compile(r"(\S+)\s*=\s*(\S+);")
s = """ctestRatio       = 30;#180/10000 = 1.8%
a       = 31;#180/10000 = 1.8%
b       = 32;#180/10000 = 1.8%
c       = 33;#180/10000 = 1.8%
#180/10000 = 1.8%
#180/10000 = 1.8%
#180/10000 = 1.8%
d       = 33;#180/10000 = 1.8%"""
f = s.splitlines()
file_path = "test.txt"

for each_line in f:
    lst = pattern.findall(each_line)
    if lst:
      for i in lst:
            key, value = i
            print('{}:{}={}'.format(file_path, key, value))

liyuping-fisher 发表于 2023-3-23 17:21:27

isdkz 发表于 2023-3-23 17:03
看看这是不是你想要的效果

参考代码:

这个方法lst打印出来是空的

liyuping-fisher 发表于 2023-3-23 17:23:57

isdkz 发表于 2023-3-23 17:03
看看这是不是你想要的效果

参考代码:

            for file_path in all_files:
                if file_path.endswith('.ini'):
                  #print("打印文件:" + file_path)
                  f = read_file(file_path)
                  # 遍历需要抓取的key并输出对应的值
                  try:
                        for each_line in f:
                            for key in PQ_keys:
                              if key in each_line.decode('utf-8'):
                                    pattern = re.compile(r"(\S+)\s*=\s*(\S+);")
                                    lst = pattern.findall(key)
                                    print(key)#这里打印出来的是key列表没问题
                                    print(lst)#这里打印出来是空,没匹配到?
                                    if lst:
                                        for i in lst:
                                          print(i)
                                          key,value = i
                                          print('{}:{}={}'.format(file_path, key, value))
                  except UnicodeDecodeError:
                        print('解码文件 {} 时发生错误'.format(file_path))

isdkz 发表于 2023-3-23 17:24:58

liyuping-fisher 发表于 2023-3-23 17:21
这个方法lst打印出来是空的

你先看看我那个参考代码中的 s 是不是像你文件中的格式,然后执行看看是不是你想要的效果

然后再相对应地改

isdkz 发表于 2023-3-23 17:28:45

liyuping-fisher 发表于 2023-3-23 17:23


            for file_path in all_files:
                if file_path.endswith('.ini'):
                  #print("打印文件:" + file_path)
                  f = read_file(file_path)
                  # 遍历需要抓取的key并输出对应的值
                  try:
                        pattern = re.compile(r"(\S+)\s*=\s*(\S+);")            # 这个可以放到外边,预编译是为了提升效率的,不用每次循环都编译一遍
                        for each_line in f:
                            for key in PQ_keys:
                              if key in each_line.decode('utf-8'):
                                    
                                  lst = pattern.findall(each_line)                  # 这里不应该是在 each_line 每一行的内容中查找吗,你那里用了 key
                                    print(key)#这里打印出来的是key列表没问题
                                    print(lst)#这里打印出来是空,没匹配到?
                                    if lst:
                                        for i in lst:
                                          print(i)
                                          key,value = i
                                          print('{}:{}={}'.format(file_path, key, value))
                  except UnicodeDecodeError:
                        print('解码文件 {} 时发生错误'.format(file_path))

liyuping-fisher 发表于 2023-3-23 17:35:41

isdkz 发表于 2023-3-23 17:28
for file_path in all_files:
                if file_path.endswith('.ini'):
          ...

解释下为啥是key
我这边key的变量是从这个列表拿的
PQ_keys = ['m_pPanelName', 'm_bPanelDualPort', 'cPanelSpreadRatio']

然后这里的each_line是文件里面的如下内容一行行的,就是通过key(m_pPanelName)去找下面文件里面的行,再获取定位到行的=和;之间的数据{:10_266:}
cRGainYpbpr2   = "0xed730"; #fdrfetrest
cGGainYpbpr2   = "0xea93d";
cBGainYpbpr2   = "0xee6fc";                        #fdrfetresttete
m_pPanelName = "0";

isdkz 发表于 2023-3-23 17:43:44

liyuping-fisher 发表于 2023-3-23 17:35
解释下为啥是key
我这边key的变量是从这个列表拿的
PQ_keys = ['m_pPanelName', 'm_bPanelDualPort', ' ...

            for file_path in all_files:
                if file_path.endswith('.ini'):
                  #print("打印文件:" + file_path)
                  f = read_file(file_path)
                  # 遍历需要抓取的key并输出对应的值
                  try:
                        pattern = re.compile(r"(\S+)\s*=\s*(\S+);")            # 这个可以放到外边,预编译是为了提升效率的,不用每次循环都编译一遍
                        for each_line in f:
                            # for key in PQ_keys:                               这个不要
                              # if key in each_line.decode('utf-8'):                     这个不要
                                    text = each_line.decode('utf-8')
                                    lst = pattern.findall(text)                  
                                    print(key)#这里打印出来的是key列表没问题
                                    print(lst)#这里打印出来是空,没匹配到?
                                  if lst:
                                        for i in lst:
                                          key, value = i
                                          if key in PQ_keys:
                                                print('{}:{}={}'.format(file_path, key, value))
                  except UnicodeDecodeError:
                        print('解码文件 {} 时发生错误'.format(file_path))

liyuping-fisher 发表于 2023-3-23 17:49:20

isdkz 发表于 2023-3-23 17:43
for file_path in all_files:
                if file_path.endswith('.ini'):
      ...

注释的那两行不能不要,因为文件里面很多行,而我搜的只是PQ_keys列表里面的几个,这个key是PQ_keys里面的元素,我要先确认这个key在PQ_keys里面,再通过这个key值去文件里面找到有key值的这一行

isdkz 发表于 2023-3-23 17:53:04

liyuping-fisher 发表于 2023-3-23 17:49
注释的那两行不能不要,因为文件里面很多行,而我搜的只是PQ_keys列表里面的几个,这个key是PQ_keys里面 ...

你先去掉看看效果

liyuping-fisher 发表于 2023-3-23 17:56:34

isdkz 发表于 2023-3-23 17:53
你先去掉看看效果

我看了的,去掉它是把文件里面的每一行处理了得到类似如下的数据
xx路径/xx文件.ini:cRGainYpbpr2="0xed730",数据太多了

isdkz 发表于 2023-3-23 18:11:02

liyuping-fisher 发表于 2023-3-23 17:56
我看了的,去掉它是把文件里面的每一行处理了得到类似如下的数据
xx路径/xx文件.ini:cRGainYpbpr2="0xed ...

            for file_path in all_files:
                if file_path.endswith('.ini'):
                  #print("打印文件:" + file_path)
                  f = read_file(file_path)
                  # 遍历需要抓取的key并输出对应的值
                  try:
                        for each_line in f:
                            for key in PQ_keys:
                              text = each_line.decode('utf-8')
                              if key in text:
                                    lst = re.findall(rf"{key}\s*=\s*(\S+?);", text)
                                    print(key)#这里打印出来的是key列表没问题
                                    print(lst)#这里打印出来是空,没匹配到?
                                    if lst:
                                        for value in lst:
                                          print('{}:{}={}'.format(file_path, key, value))
                  except UnicodeDecodeError:
                        print('解码文件 {} 时发生错误'.format(file_path))

liyuping-fisher 发表于 2023-3-23 20:14:23

isdkz 发表于 2023-3-23 18:11
for file_path in all_files:
                if file_path.endswith('.ini'):
          ...

lst = re.findall(fr"\s*=\s*(\S+?;)", each_line.decode('utf-8'))
                                             ^

这里有个语法错误,我打死也没找到语法错误,用的python版本是3.4,指向的好像是双引号~

isdkz 发表于 2023-3-23 20:17:35

liyuping-fisher 发表于 2023-3-23 20:14
lst = re.findall(fr"\s*=\s*(\S+?;)", each_line.decode('utf-8'))
                                 ...

因为我用了一个 f-string 的语法是 python 3.6 以后才有的,你可以改一下

            for file_path in all_files:
                if file_path.endswith('.ini'):
                  #print("打印文件:" + file_path)
                  f = read_file(file_path)
                  # 遍历需要抓取的key并输出对应的值
                  try:
                        for each_line in f:
                            for key in PQ_keys:
                              text = each_line.decode('utf-8')
                              if key in text:
                                    lst = re.findall(r"{}\s*=\s*(\S+?);".format(key), text)
                                    print(key)#这里打印出来的是key列表没问题
                                    print(lst)#这里打印出来是空,没匹配到?
                                    if lst:
                                        for value in lst:
                                          print('{}:{}={}'.format(file_path, key, value))
                  except UnicodeDecodeError:
                        print('解码文件 {} 时发生错误'.format(file_path))
页: [1]
查看完整版本: 正则匹配问题