鱼C论坛

 找回密码
 立即注册
查看: 3636|回复: 19

[已解决]正则匹配问题

[复制链接]
发表于 2023-3-23 15:52:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

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))  
最佳答案
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'))
                                 ...

[b]因为我用了一个 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))
[/b]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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比较。如果相等,则打印文件路径、键和值。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-23 16:51:52 | 显示全部楼层
isdkz 发表于 2023-3-23 15:59
正则表达式可以用 ctestRatio\s*=\s*(\S+);

示例代码:

没太明白,ctestRatio这个是个变量,也就是代码中的key,因为我有很多key
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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搜索出来的结果),在取其=和;之间的数据
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

也就是你要匹配每一个等号和分号之间的内容作为 value,前面的内容作为 key?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-23 16:55:45 | 显示全部楼层
isdkz 发表于 2023-3-23 16:54
也就是你要匹配每一个等号和分号之间的内容作为 value,前面的内容作为 key?

是的是的,用key这个变量遍历每一行,然后每一行的数据大概就是“"ctestRatio       = 30;#180/10000 = 1.8%"这样的,我要等号前面的就是key,=和;之间的是我要提起的value
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-23 17:21:27 | 显示全部楼层
isdkz 发表于 2023-3-23 17:03
看看这是不是你想要的效果

参考代码:

这个方法lst打印出来是空的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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)) 
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-23 17:24:58 | 显示全部楼层
liyuping-fisher 发表于 2023-3-23 17:21
这个方法lst打印出来是空的

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

然后再相对应地改
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-23 17:28:45 | 显示全部楼层

            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))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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)去找下面文件里面的行,再获取定位到行的=和;之间的数据
cRGainYpbpr2   = "0xed730"; #fdrfe  trest
cGGainYpbpr2   = "0xea93d";
cBGainYpbpr2   = "0xee6fc";                        #fdrfe  tresttete
m_pPanelName = "0";
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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值的这一行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

你先去掉看看效果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-23 17:56:34 | 显示全部楼层
isdkz 发表于 2023-3-23 17:53
你先去掉看看效果

我看了的,去掉它是把文件里面的每一行处理了得到类似如下的数据
xx路径/xx文件.ini:cRGainYpbpr2="0xed730",数据太多了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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,指向的好像是双引号~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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'))
                                 ...

[b]因为我用了一个 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))
[/b]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-24 01:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表