如何匹配和解析不同形式的标签中的特定信息

How to match and parse specific info in tags with varying form

我需要解析和处理作为 (UTF-8) 文本文件从第 3 方推送到我们的网络服务的输入数据。输入文件包含一般形式的标签

<{ _N ('some_domain_id','this can be an arbitary string',{'a':'b','c':'d'}) }>
-- --   --------------   ------------------------------  -----------------  --
        ^                 ^                              ^
        i need to         |                              this part is 
        extract this      and this (payload)             optional

这些标签无论如何都可以出现在文本文件中,不能假设它们的分布以及标签之间的内容。 <{_N}> 也存在于任何给定的有效标签中,但在不破坏值的情况下,它们之间可能会有空格(例如 <{ 和 [=14= 之间) ]) 有了这些信息,我的初始测试集是有限的,我当前的实现是一个正则表达式以及 ,

处的结果拆分

该服务已经运行了一段时间,我不得不意识到虽然绝大多数标签都被正确捕获,但仍有少量标签包含异常并且无法被此实现识别。

注意事项(有效载荷部分可能发生的事情):

以下是我发现的一些无法解析或产生错误结果(甚至比不识别更糟糕)的示例标签。

<{_N( 'some_domain_id' , 'this can ( be an arbitary ) string',{'a':'b','c':'d'})}>

- 无法识别,注意括号,它们可以出现在数据字符串的任何位置,甚至不需要平衡(例如:https://regex101.com/r/BCiaaj/1

<{_N( 'some_domain_id' , 'this can  be an arbitary  string' {'a':'b','c':'d'})|e('modifier')}>
<{_N( 'some_domain_id' , 'this can  be an arbitary string')|e('modifier')}>

实验上,我已经尝试了一些其他的正则表达式,但它们总是在我的扩展测试集中的一个或多个标签上失败,例如

所以我的问题是因为我不是真正的正则表达式专家

非常感谢任何帮助!

为什么你不能只检索你需要的部分(在单引号中);

//example 1
$str = '<{_N( \'some_domain_id\' , \'this can ( be an arbitary ) string\',{\'a\':\'b\',\'c\':\'d\'})}>';
test_pregex($str);

//example 2
$str = '<{_N(\'some_domain_id\'      , \'this can ( be an arbitary ) string\'  ,{\'a\':\'b\',\'c\':\'d\'})}  >';
test_pregex($str);

//example 3
$str = '<{_N( \'some_domain_id\' , \'this can ( be an arbitary ) string\')|e(\'modifier\')}>';
test_pregex($str, '\'modifier\'');

function test_pregex($str, $optional = "{'a':'b','c':'d'}") {
    $re = '/\'([^\']*?)\'|(\{\'[^\']*?\'.+?})/m';
    preg_match_all($re, $str, $matches);
    $matches = $matches[0];
    var_export($matches);   
    assert($matches[0] == "'some_domain_id'");
    assert($matches[1] == "'this can ( be an arbitary ) string'");
    assert($matches[2] == $optional);
}

输出将是所有三种情况,没有断言警告。然后您可以进一步处理您需要的内容。

您可以使用

<{\s*_N\s*\(\s*'([^\']*(?:\.[^\']*)*)'\s*,\s*'([^\']*(?:\.[^\']*)*)'\s*(.*?)}>

regex demo

详情:

  • <{\s* - <{ 加上 0+ 个空格
  • _N - 标签开始
  • \s*\(\s* - 包含 0+ 个空格的 (
  • '([^\']*(?:\.[^\']*)*)' - 可能包含转义单引号和其他字符的单引号字符串文字(内部内容被捕获到捕获组 #1)
  • \s*,\s* - 包含 0+ 个空格的 ,
  • '([^\']*(?:\.[^\']*)*)' - 可能包含转义单引号和其他字符的单引号字符串文字(内部内容被捕获到捕获组 #2)
  • \s* - 0+ 个空格
  • (.*?) - 任何 0+ 个字符尽可能少,直到第一个
  • }> - 文字字符序列 }>.