我对正则表达式很新,但决定使用它们来反序列化PHP数组。以下是一些背景信息:
我为django中用PHP编写的公司重写了一个基于数据库的网站。与公司和行业存在M2M关系。在之前的模型中,它是通过使用序列化的PHP数组解决的,所以我现在必须正确地同步所有内容。我的第一次尝试是一些分裂和切割,它真的很难看,所以我决定深入研究正则表达式。这就是我现在所做的事情(它工作得非常好):
def unserialize_array(serialized_array):
import re
matched_sub = re.search('^a:\d+:\{i:\d+;s:\d+:"(.*?)";\}$', serialized_array).group(1)
industry_list = re.sub('";i:\d+;s:\d+:"', "? ", matched_sub).split("? ")
new_dict = dict(enumerate(industry_list))
return new_dict
我想知道我是不是用一个正则表达而不是两个来做所有这些。
答案 0 :(得分:0)
建议将re.sub
用于回调,这将在递归中调用unserialize_array。
答案 1 :(得分:0)
更新:已更新以正确处理转义引号\"
(实际上已写入\\"
)和任何转义序列(作为转义转义后的转义引号{{1}那是\\\"
)。
我认为,如果我正确理解了你输入的结构,你就可以重写你的方法:
\\\\\\"
假设输入(未在您的问题中明确说明):
def unserialize_array(serialized_array):
import re
return dict(enumerate(re.findall(r'"((?:[^"\\]|\\.)*)"', serialized_array)))
<强>输出强>
{0:&#39; industry1 \\\&#34; A \&#34;&#39;,1:&#39; \&#34; industry2 \&#34;&#39; ,2:&#39; industry3&#39;}
(实际上:a:3:{i:1;s:9:"industry\\\\\\"A\\"";i:2;s:9:"\\"industry2\\"";i:3;s:9:"industry3"}
)
工作原理
没有必要匹配序列化数组的整个结构,因为我们只对字符串内容感兴趣。正则表达式{0: 'industry1\\\\\\"A\\"', 1: '\\"industry2\\"', 2: 'industry3'}
只是提取每个字符,直到遇到逃脱&#39; \ (在这种情况下,接受转义+另一个字符)或结束双引号"((?:[^"\\]|\\.)*)"
。
捕获组确保在最终结果中删除双引号。
最后,re.findall方法在一次调用中返回由我们所需结果组成的字符串列表。
这是"
的特性,如果至少一个捕获组出现匹配(或者在我们的情况下是捕获组),则覆盖整个匹配。事实上,文档声明:
如果模式中存在一个或多个组,则返回组列表;如果模式有多个组,这将是一个元组列表。