正则表达式只匹配某一行的一部分

时间:2016-08-01 18:16:19

标签: python regex python-3.x

我有一些配置文件,我需要从中提取一些值。例如,我有这个:

PART
{
    title = Some Title
    description = Some description here.    // this 2 params are needed 
    tags = qwe rty    // don't need this param
    ...
}

我需要提取某个参数的值,例如description的值。我如何使用正则表达式在Python3中执行此操作?

3 个答案:

答案 0 :(得分:2)

这是正则表达式,假设文件文本位于txt

import re

m = re.search(r'^\s*description\s*=\s*(.*?)(?=(//)|$)', txt, re.M)
print(m.group(1))

让我解释一下。 ^在行首处匹配。 然后\s*表示零个或多个空格(或制表符) description是您找到价值部分的锚点。 之后,我们希望通过表示=之前或之后使用可选空格\s*=\s*进行签名。 然后我们通过表示=来捕获(.*?)和可选空格之后的所有内容。该表达式由括号捕获。在括号内,我们说你可以用非贪婪的方式(问号)匹配任何东西(圆点),也就是说,一旦匹配下面的表达式就停止。

以下表达式是一个先行表达式,以(?=开头,与(?=之后的东西匹配。 而那个东西实际上是两个选项,由竖线|分隔。

条形图左侧的第一个选项是//(在括号中使其成为垂直条选择操作的原子单位),即注释的开头,我想,你不想捕捉。 第二个选项是$,表示行的结尾,如果行上没有注释//,则会到达。 因此,我们会在第一个=符号后查找所有内容,直到我们遇到//模式,或者我们遇到行尾。这是(?=(//)|$)部分的本质。

我们还需要re.M标志,告诉正则表达式引擎我们希望^$分别匹配行的开头和结尾。没有标志,它们匹配整个字符串的开头和结尾,这不是我们想要的情况。

答案 1 :(得分:0)

更好的方法是使用已建立的配置文件系统。 Python内置了对configparser模块中类似INI的文件的支持。

但是,如果您只是绝望地需要在description之后获取该文件中的文本字符串,那么您可以这样做:

def get_value_for_key(key, file):
    with open(file) as f:
        lines = f.readlines()
    for line in lines:
        line = line.lstrip()
        if line.startswith(key + " ="):
            return line.split("=", 1)[1].lstrip()

您可以通过以下呼叫使用它:get_value_for_key("description", "myfile.txt")。如果找不到任何内容,该方法将返回None。假设您的文件将被格式化为有空格且密钥名称后面的等号,例如key = value

这完全避免了正则表达式,并保留了值右侧的任何空格。 (如果这对您不重要,您可以使用strip代替lstrip。)

为什么要避免正则表达式?它们非常昂贵,而且对于这种情况来说并不理想。使用简单的字符串匹配这样可以避免导入模块并简化代码。但我真的要说转换为支持的配置文件格式。

答案 2 :(得分:-1)

这是一个非常简单的正则表达式,你只需要一个积极的lookbehind,并可选择删除注释。 (通过将?(//)?附加到正则表达式

来执行此操作)
r"(?<=description = ).*"

Regex101 demo