我需要解析并处理推送到我们的webservice中的输入数据,作为来自第三方的(UTF-8)文本文件。输入文件包含一般形式的标签
<{ _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
和}>
也会出现,但两者之间可能存在空格而不会中断这些值(例如<{
和{{1}之间})
有了这些信息,我的初始测试集是有限的,我当前的实现是一个正则表达式以及_N
,
(示例:https://regex101.com/r/NuJD2V/1)/<{\s*_N\s*\(([^\)]*)\)\s*}>?/g
与'some_domain_id' , 'this can be an arbitary string',{'a':'b','c':'d'}
str_getcsv($match,',','\'','\\')
结果的前两个部分,将其他结果视为可选str_getcsv
和some_domain_id
可以根据需要进行裁剪和处理服务现在已经有一段时间了,我必须意识到尽管绝大多数标签都被正确捕获,但是有少量标签包含异常,并且无法被此实现识别。
警告(有效负载部分可能发生的事情):
this can be an arbitary string
以下是我发现的一些无法解析或产生错误结果的样本标签(甚至比不识别更糟糕)。
\'
- 无法识别,请注意括号,它们可以出现在数据字符串的任何位置,它们甚至不需要平衡(例如:https://regex101.com/r/BCiaaj/1)
<{_N( 'some_domain_id' , 'this can ( be an arbitary ) string',{'a':'b','c':'d'})}>
<{_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')}>
周围也可能有空格(例如:https://regex101.com/r/XmR2uO/1)在实验上,我已经尝试了一些其他正则表达式,但它们总是在我的扩展测试集中的一个或多个标记上失败,例如。
|
- 捕获修饰符大小写,但在相关字符串中的括号上失败所以我的问题是因为我不是真正的正则表达式专家
非常感谢任何帮助!
答案 0 :(得分:1)
您可以使用
<{\s*_N\s*\(\s*'([^\\']*(?:\\.[^\\']*)*)'\s*,\s*'([^\\']*(?:\\.[^\\']*)*)'\s*(.*?)}>
请参阅regex demo
<强>详情:
<{\s*
- <{
加0+空格_N
- 标签开始\s*\(\s*
- 包含0 +空格的(
'([^\\']*(?:\\.[^\\']*)*)'
- 单引号字符串文字,可能包含转义的单引号和其他字符(内部内容被捕获到捕获组#1中)\s*,\s*
- 包含0 +空格的,
'([^\\']*(?:\\.[^\\']*)*)'
- 单引号字符串文字,可能包含转义的单引号和其他字符(内部内容被捕获到捕获组#2中)\s*
- 0+ whitespaces (.*?)
- 在第一个}>
- 文字字符序列}>
。答案 1 :(得分:0)
为什么你不能只检索你需要的部分(在单引号中);
//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);
}
输出将是所有三种情况,没有断言警告。然后,您可以进一步处理所需内容。