如何匹配和解析不同形式的标签中的特定信息
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= 之间) ])
有了这些信息,我的初始测试集是有限的,我当前的实现是一个正则表达式以及 ,
处的结果拆分
- 正则表达式
/<{\s*_N\s*\(([^\)]*)\)\s*}>?/g
(示例:https://regex101.com/r/NuJD2V/1)
- 然后拆分结果匹配
'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
可以根据需要裁剪加工
该服务已经运行了一段时间,我不得不意识到虽然绝大多数标签都被正确捕获,但仍有少量标签包含异常并且无法被此实现识别。
注意事项(有效载荷部分可能发生的事情):
- 负载中的括号
- 负载中的转义引号
\'
- _N 调用最外层括号后的可选修饰符(见下文)
以下是我发现的一些无法解析或产生错误结果(甚至比不识别更糟糕)的示例标签。
<{_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')}>
- 无法识别,请注意 _N 元素最外层括号后的额外(可选)修饰符。修饰符可以由不同的字母 (e,r,w) 和任意字符串参数组成,链运算符周围也可能有空格
|
(示例:https://regex101.com/r/XmR2uO/1)
实验上,我已经尝试了一些其他的正则表达式,但它们总是在我的扩展测试集中的一个或多个标签上失败,例如
/_N\s*(\(\s*(?:\(??[^(]*?\s*\)))+/
- 捕获修饰符大小写,但在相关字符串 中的括号中失败
所以我的问题是因为我不是真正的正则表达式专家
- 这可以用正则表达式解决吗?如果可以,有人能在正确的方向上提示我吗?
- 在 vanilla php 7+ 没有 installing/using 一些外部库的情况下是否有更好的可行解决方案
非常感谢任何帮助!
为什么你不能只检索你需要的部分(在单引号中);
//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*(.*?)}>
详情:
<{\s*
- <{
加上 0+ 个空格
_N
- 标签开始
\s*\(\s*
- 包含 0+ 个空格的 (
'([^\']*(?:\.[^\']*)*)'
- 可能包含转义单引号和其他字符的单引号字符串文字(内部内容被捕获到捕获组 #1)
\s*,\s*
- 包含 0+ 个空格的 ,
'([^\']*(?:\.[^\']*)*)'
- 可能包含转义单引号和其他字符的单引号字符串文字(内部内容被捕获到捕获组 #2)
\s*
- 0+ 个空格
(.*?)
- 任何 0+ 个字符尽可能少,直到第一个
}>
- 文字字符序列 }>
.
我需要解析和处理作为 (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= 之间) ])
有了这些信息,我的初始测试集是有限的,我当前的实现是一个正则表达式以及 ,
- 正则表达式
/<{\s*_N\s*\(([^\)]*)\)\s*}>?/g
(示例:https://regex101.com/r/NuJD2V/1) - 然后拆分结果匹配
'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
可以根据需要裁剪加工
该服务已经运行了一段时间,我不得不意识到虽然绝大多数标签都被正确捕获,但仍有少量标签包含异常并且无法被此实现识别。
注意事项(有效载荷部分可能发生的事情):
- 负载中的括号
- 负载中的转义引号
\'
- _N 调用最外层括号后的可选修饰符(见下文)
以下是我发现的一些无法解析或产生错误结果(甚至比不识别更糟糕)的示例标签。
<{_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')}>
- 无法识别,请注意 _N 元素最外层括号后的额外(可选)修饰符。修饰符可以由不同的字母 (e,r,w) 和任意字符串参数组成,链运算符周围也可能有空格
|
(示例:https://regex101.com/r/XmR2uO/1)
实验上,我已经尝试了一些其他的正则表达式,但它们总是在我的扩展测试集中的一个或多个标签上失败,例如
/_N\s*(\(\s*(?:\(??[^(]*?\s*\)))+/
- 捕获修饰符大小写,但在相关字符串 中的括号中失败
所以我的问题是因为我不是真正的正则表达式专家
- 这可以用正则表达式解决吗?如果可以,有人能在正确的方向上提示我吗?
- 在 vanilla php 7+ 没有 installing/using 一些外部库的情况下是否有更好的可行解决方案
非常感谢任何帮助!
为什么你不能只检索你需要的部分(在单引号中);
//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*(.*?)}>
详情:
<{\s*
-<{
加上 0+ 个空格_N
- 标签开始\s*\(\s*
- 包含 0+ 个空格的(
'([^\']*(?:\.[^\']*)*)'
- 可能包含转义单引号和其他字符的单引号字符串文字(内部内容被捕获到捕获组 #1)\s*,\s*
- 包含 0+ 个空格的,
'([^\']*(?:\.[^\']*)*)'
- 可能包含转义单引号和其他字符的单引号字符串文字(内部内容被捕获到捕获组 #2)\s*
- 0+ 个空格(.*?)
- 任何 0+ 个字符尽可能少,直到第一个}>
- 文字字符序列}>
.