python替代正则表达式搜索返回元组无

Posted

技术标签:

【中文标题】python替代正则表达式搜索返回元组无【英文标题】:python alternative regex search return tuple with None 【发布时间】:2022-01-12 13:29:06 【问题描述】:

我有以下脚本,如果可用,它会获取 tnsfiles 的 service_name,如果不可用,它会获取 SID 它似乎工作正常,但它返回我无法解析的元组

#!/usr/bin/env python

import re

regexes = re.compile(r'SERVICE_NAME\s?=\s?(.+?)\)|SID\s?=\s?(.+?)\)')

with open('tnsnames.ora.test') as tns_file:
    for tnsname in tns_file:
        match = regexes.search(tnsname)

        if match:
          print(match.groups())

脚本返回以下内容:

(None, 'db1')
('db2', None)
('db3', None)

但我只想返回数据库的名称而不是 None

如何从输出中去除“无”。 我不能使用 re.findall,因为 tnsnames 中有一些行具有 service_name 和 sid,然后我会有重复项。

如何解析匹配正则表达式对象的输出以忽略无?

【问题讨论】:

【参考方案1】:

如果您想要一个捕获组来防止两个组由于 alternation 而为空,您可以将交替移动到 SERVICE_NAME 和 SID (?:SERVICE_NAME|SID) 之间的模式开头,并将其设为非捕获组。

如果两个单词都不能成为更大单词的一部分,您可以在模式前添加一个单词边界 \b

(?:SERVICE_NAME|SID)\s?=\s?(.+?)\)

说明

(?:SERVICE_NAME|SID) 匹配 SERVICE_NAME 或 SID \s?=\s? 匹配被可选空白字符包围的 = (.+?)\) 匹配除换行符以外的任何字符非贪婪,然后匹配 )

Regex demo

【讨论】:

【参考方案2】:

您正在使用.groups() 方法返回所有捕获的值,即使它们是空的。由于正则表达式在每个中都包含与捕获组的交替,因此在有效匹配时,其中一个将始终为空。

对此的通用解决方案是从两项元组中过滤出 None 值,您可以使用a lot of approaches 来做到这一点。一种方法是连接两个值:

m = match.groups()
print(r''.format(m[0] or '', m[1] or ''))

m[x] or '' 语法在这里是可以的,因为我们只能在 match.groups() 中有一个字符串或 None

另一种解决方案是重新编写模式,使其仅包含 1 个捕获组

很容易使模式包含单个组,因为括号之间的匹配部分在两种替代方案中都是重复的:

r'(?:SERVICE_NAME|SID)\s*=\s*([^)\r\n]+)'
  ^^^^^^^^^^^^^^^^^^^^

查看regex demo 和regex graph:

详情

(?:SERVICE_NAME|SID) - 匹配 SERVICE_NAMESIDnon-capturing group \s*=\s* - = 包含 0+ 个空格 ([^)\r\n]+) - 第 1 组:除)、CR 和 LF 之外的任何字符,一次或多次出现(由于最初尝试中的 . 而被排除)。

【讨论】:

以上是关于python替代正则表达式搜索返回元组无的主要内容,如果未能解决你的问题,请参考以下文章

Python 正则表达式解析字符串并返回元组

Python:在元组中存储许多正则表达式匹配?

Python正则表达式及常用匹配

Python正则表达式及常用匹配

2019-1-17 python正则表达式

python3的正则表达式(regex)