Python:使用正则表达式反序列化PHP数组

时间:2016-01-04 12:57:12

标签: php python arrays regex

我对正则表达式很新,但决定使用它们来反序列化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

我想知道我是不是用一个正则表达而不是两个来做所有这些。

2 个答案:

答案 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方法在一次调用中返回由我们所需结果组成的字符串列表。

这是"的特性,如果至少一个捕获组出现匹配(或者在我们的情况下是捕获组),则覆盖整个匹配。事实上,文档声明:

  

如果模式中存在一个或多个组,则返回组列表;如果模式有多个组,这将是一个元组列表。