Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在不分组的情况下匹配OR表达式?_Python_Regex - Fatal编程技术网

Python 如何在不分组的情况下匹配OR表达式?

Python 如何在不分组的情况下匹配OR表达式?,python,regex,Python,Regex,我正在解析bind db files1,其中的行与 例如,我想捕捉第一个字符串www.sales,但仅当行中有A或CNAME时 由于使用了\s*\s+.*\sA\s |\sCNAME\s作为代码中的正则表达式,我使用了: with open(file) as f: db = f.read() z = re.finditer(r"\s*(\S+).*(\sA\s|\sCNAME\s)", db) z = [i.group(0) for i in z] 其结果是 [' www.sale

我正在解析bind db files1,其中的行与

例如,我想捕捉第一个字符串www.sales,但仅当行中有A或CNAME时

由于使用了\s*\s+.*\sA\s |\sCNAME\s作为代码中的正则表达式,我使用了:

with open(file) as f:
   db = f.read()
z = re.finditer(r"\s*(\S+).*(\sA\s|\sCNAME\s)", db)
z = [i.group(0) for i in z]
其结果是

['    www.sales\t1D IN\tA\t', '\n    www.learning\t1D IN\tCNAME\t']
我对这个结果有两个问题,我不理解:

为什么www.sales没有单独匹配第一个案例,而是与regex表达式中描述的全部内容匹配?上面的regex101链接显示了正确的分组。 我怎样才能摆脱第二组呢?我仍然想把这个条款作为一项要求,也就是说,让a或CNAME在这条线上,但我对保持比赛不感兴趣 1我知道dns模块,但由于各种原因,它不能满足我的需要


2注意以下关于绑定文件格式的注释:是的,我知道此绑定罚款不正确。我所做的是复制/粘贴这篇文章的源代码,在文本标记语法之前使用空格进行测试,最终得到这样一个文件。我稍微扩展了我的正则表达式以考虑到这一点-实际文件是正确的。

为了避免创建捕获组,请使用非捕获组,而不是。。。使用?:…:

您还可以使用.group0获取整个匹配行。如果你只想参加比赛的第一组,就参加第1组。然后也不需要匹配初始空格;您没有锚定到线的起点:

z = re.finditer(r"(\S+).*(?:\sA\s|\sCNAME\s)", db)
z = [i.group(1) for i in z]
最后,对于一个组,您可以使用re.findall生成一个列表:

z = re.findall(r"(\S+).*(?:\sA\s|\sCNAME\s)", db)
演示:

我不需要在A或CNAME周围使用空格,而是在单词边界\b上定位,并在DNS名称中查找一组更有限的允许字符,或许还可以匹配in record class字段:

r'([a-z0-9-.]+).*IN\s+(?:A|CNAME)\b'
如果样本匹配,则输入文件的每一行似乎都有前导空格;实际的绑定格式不允许这样的空白

^\s*(\S+)(?=.*?\b(?:A|CNAME)\b)
您可以将此正则表达式与re.findall一起使用。它将返回所有捕获字符串的列表。请参阅演示


你的意思是?你只需要i.group1,因为www.sales在第1组中。为什么在匹配的名称前有空格?一个合适的区域文件不应该缩进行,因为缩进使它成为一个续行。@Barmar:你说得对,我在问题脚注2中添加了一条注释。你不能忽略初始空格。在DNS文件中,缩进的行是前一行的延续,第一个字段不是名称。我不确定他为什么在结果中有这些前导空格,区域文件中的行不应该缩进。@Barmar:示例匹配在每一行的开始处显示空白;我故意把重点放在问题中的两个问题上,而不是他们对BIND格式的解析有多正确,但是他们给出的示例从外观上看实际上不是一个有效的BIND db文件。
>>> import re
>>> db = '''\
... www.sales   1D IN   A   10.0.0.1
... www.learning    1D IN   CNAME   something
... www.it 1D IN    AAAA    1::0::whatever
... '''
>>> re.findall(r"(\S+).*(?:\sA\s|\sCNAME\s)", db)
['www.sales', 'www.learning']
r'([a-z0-9-.]+).*IN\s+(?:A|CNAME)\b'
^\s*(\S+)(?=.*?\b(?:A|CNAME)\b)
with open(file) as f:
   db = f.read()
print re.findall(r"^\s*(\S+)(?=.*?\b(?:A|CNAME)\b)",db,re.M)