字符串后获取文本

时间:2019-01-03 01:42:24

标签: python regex

我正在寻找帮助来创建一个正则表达式,该正则表达式可以使用Python在给定的字符串之后获取特定的文本。

我正在尝试从页面中提取JSON,就像这样:

    var config = {aslkdjsakljdkalsj{asdasdas}askldjaskljd};

我需要一个可以从第一个{到} =>且没有分号的正则表达式

我尝试使用

    config = .*?(?=\}\;)

但输出是

    config = {sadasdasdas{a}asdasdasd

它得到config =部分,而没有得到最后一个}

我该如何解决?

1 个答案:

答案 0 :(得分:1)

如果您的JS行有保证在终止;之前不包含换行符,那么问题就很简单-匹配var config =,然后是非将换行符捕获到一组中,然后匹配分号和该行的末尾。如果JSON以'分隔,则例如使用模式

var config = '(.+)';$

并提取第一组。

input = '''
  var config = '{ "foo": "b\\ar", "ba{{}}}{{z": ["buzz}", "qux", {"innerprop": "innerval"}]}';
  var someOtherVar = 'bar';
'''
match = re.search("(?m)var config = '(.+)';$", input);

如果不保证JSON 不在自己的行上,那么它会复杂得多。解析像JSON这样的嵌套结构是困难的-使用正则表达式可以解决一般问题的唯一方法是结构是事先已知的(通常不是这种情况,并且在模式中可能需要很多重复的代码),或者使用的RE引擎支持递归匹配。没有这些,就无法表达在模式中使用{平衡}的需求。

幸运的是,如果您使用的是Python,即使Python的本机RE不支持递归,也可以使用regex module。您还需要确保JSON中的字符串 内的{}不会影响当前的嵌套级别。对于原始字符串,您需要类似

的模式
var config = String\.raw`\K({(?:"(?:\\|\\"|[^"])*"|[^{}]|(?1))*})(?=`;)

捕获组的外部是

var config = String\.raw`\K({ ... })(?=`;)

将所需的行和字符串定界符与捕获组匹配

{(?:"(?:\\|\\"|[^"])*"|[^{}]|(?1))*}

表示-{,后跟任意多个

  • "(?:\\|\\"|[^"])*"-匹配JSON中的字符串(键或值),从其起始定界符到其结束定界符,忽略转义的",或
  • [^{}]-匹配非{}的任何内容-其他字符可以忽略,因为我们只想正确地设置嵌套级别,或者
  • (?1)-递归整个第一个捕获组(与{ ... }匹配的捕获组)

这将确保{ }括号在模式结尾处得到平衡。


但是-上面是一个使用String.raw的示例,其中Javascript代码中的文字反斜杠表示字符串中的文字反斜杠。另一方面,在使用'分隔符的情况下,JS中的文字反斜杠必须 double 转义,因此上面的输入看起来像

var config = '{ "foo": "b\\\\ar", "ba{{}}}{{z": ["buzz}", "qux", {"innerprop": "innerval"}]}';

还需要在模式中对转义的反斜杠进行两次转义:

var config = '\K({(?:"(?:\\\\|\\\\"|[^"])*"|[^{}]|(?1))*})(?=';)

https://regex101.com/r/8rSrGf/1

这非常复杂。如果可能的话,我建议您采用第一种方法或其替代方法。