我有包含以下结构的文本文件
{1,"StructEx",
[{1,"Element_1",[{2,"name","exampleName"},{3,"exampleValue",1},{2,"exampleComment","foo"}]},
[{1,"Element_2",[{2,"name","exampleName2"},{3,"exampleValue",2},{2,"exampleComment","bar"}]}]}
括号中的第一个值是数据类型。 我需要返回的regex表达式(通过几次迭代) StructEx中的所有元素,所以我可以将它打包成类似的东西
["StructEx"]=>
array(2) {
["Element_1"]=>
array(3) {
["name"]=>
string(11) "exampleName"
["exampleValue"]=>
int(1)
["exampleComment"]=>
string(3) "foo"
}
["Element_2"]=>
array(3) {
["name"]=>
string(12) "exampleName2"
["exampleValue"]=>
int(2)
["exampleComment"]=>
string(3) "bar"
}
}
答案 0 :(得分:1)
假设嵌套是任意深的,那么答案是不,你不能用正则表达式解析这种文本文档。如果深度是有限的,那很痛苦,但是可行。
为了更详细地回答你的问题,让我们介绍一些令人敬畏的干燥理论。
让我们将字母表Σ定义为非空符号集(技术上更正确的定义来自类别理论,将字母表视为非空的自由对象,但为了论证,这个定义就足够了
在我们的字母表Σ中,我们可以在字母表中定义一组所有有限字符串(读取:单词),即:
Σ= {s 1 ,s 2 ,...,s n }
Σ* = {ε}∪{s i1 s i2 ... s im | s ik ∈Σ,m> 0,1≤k≤n},其中ε是空字符串
例如,这意味着如果我们有一个字母Σ = {a, b, c}
,Σ*中的某些字词将是aaaaaa
,abababa
,而不是abd
,因为我们甚至不知道d
存在。
鉴于字母表Σ,我们有正则表达式,如ab*|c
。我正在跳过正则表达式的正式定义,以减少它的混乱,所以让我们假设它是我们普通的“实用”正则表达式。
每个正则表达式定义定义常规语言,例如在此示例中,语言由单词a
,ab
,c
,abbbbbc
组成,但不包含abc
。
每种常规语言都可以表示为finite automaton,这是一种可以识别正则表达式的设备。对于前面提到的正则表达式ab*|c
,自动机看起来像这样:
0是开始状态,双圈是接受状态。简而言之,自动机在状态0开始消耗一个单词的每个字母并根据过渡箭头移动。如果它最终处于接受状态,我们说接受字符串。否则,我们说它拒绝它。
所以在这种情况下,将字符串abb
送入我们的机器:
a
,转到州1 b
,转到州3 b
,转到州3 让我们看看当我们将abc
送入我们的机器时会发生什么:
a
,转到州1 b
,转到州3 c
,无处可动,字符串被拒绝所以我们的正则表达式与abc
不匹配。所有这些都与实际正则表达式基本相同,并附加了一些理论。
有一个定理指出每种常规语言都是有限自动机可识别的。这意味着,如果存在可以匹配所需模式的常规语言(和基础正则表达式),那么应该是一个等价的有限自动机。
但是你的模式中的嵌套具有无限的深度。因此,您需要一个无限大的有限自动机,它等同于常规语言,这与有限自动机的定义相矛盾。
正如你所看到的,我跳过了正则表达式的归纳定义,类别理论视角下的有限自动机,操作中的闭包以及其他一些正式的东西。欢迎您在上述参考链接中阅读相关内容。