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_NAME
或 SID
的 non-capturing group
\s*=\s*
- =
包含 0+ 个空格
([^)\r\n]+)
- 第 1 组:除)
、CR 和 LF 之外的任何字符,一次或多次出现(由于最初尝试中的 .
而被排除)。
【讨论】:
以上是关于python替代正则表达式搜索返回元组无的主要内容,如果未能解决你的问题,请参考以下文章