匹配json字符串的正则表达式
在处理日志时, 发现文本里夹杂有json字符串, 希望能准确提取出来. 于是就有了下面这个正则表达式:
(?<json>(?:{s*"(?:\"|[^"])+"s*:s*(?:(?P>json)|"(?:\"|[^"])+"|[-+]?(0|[1-9]d*)(?:.[-+]?(0|[1-9]d*))?(?:[eE][-+]?(0|[1-9]d*))?|(?:true|false)|null)(?:s*,s*"(?:\"|[^"])+"s*:s*(?:(?P>json)|"(?:\"|[^"])+"|[-+]?(0|[1-9]d*)(?:.[-+]?(0|[1-9]d*))?(?:[eE][-+]?(0|[1-9]d*))?|(?:true|false)|null))*s*}|[s*(?:(?P>json)|"(?:\"|[^"])+"|[-+]?(0|[1-9]d*)(?:.[-+]?(0|[1-9]d*))?(?:[eE][-+]?(0|[1-9]d*))?|(?:true|false)|null)(?:s*,s*(?:(?P>json)|"(?:\"|[^"])+"|[-+]?(0|[1-9]d*)(?:.[-+]?(0|[1-9]d*))?(?:[eE][-+]?(0|[1-9]d*))?|(?:true|false)|null))*s*]))
匹配规则完全符合官网规范说明 http://www.json.org
生成正则时得益于两种思想: 分而治之和递归
以下是生成正则的代码和简单的测试.
<?php
function json_reg() {
echo "<xmp>";
//基础元素
$r_int = "-?d+"; //整数: 100, -23
$r_blank = "s*"; //空白
$r_obj_l = "\{".$r_blank; // {
$r_obj_r = $r_blank."\}"; // }
$r_arr_l = "\[".$r_blank; // [
$r_arr_r = $r_blank."\]"; // [
$r_comma = $r_blank.",".$r_blank; //逗号
$r_colon = $r_blank.":".$r_blank; //冒号
//基础数据类型
$r_str = ""(?:\\"|[^"])+""; //双引号字符串
$r_num = "{$r_int}(?:\.{$r_int})?(?:[eE]{$r_int})?"; //数字(整数,小数,科学计数): 100,-23; 12.12,-2.3; 2e9,1.2E-8
$r_bool = "(?:true|false)"; //bool值
$r_null = "null"; //null
//衍生类型
$r_key = $r_str; //json中的key
$r_val = "(?:(?P>json)|{$r_str}|{$r_num}|{$r_bool}|{$r_null})"; //json中val: 可能为 json对象,字符串,num, bool,null
$r_kv = "{$r_key}{$r_colon}{$r_val}"; //json中的一个kv结构
$r_arr = "{$r_arr_l}{$r_val}(?:{$r_comma}{$r_val})*{$r_arr_r}"; //数组: 由val列表组成
$r_obj = "{$r_obj_l}{$r_kv}(?:{$r_comma}{$r_kv})*{$r_obj_r}"; //对象: 有kv结构组成
$reg = "/(?<json>(?:{$r_obj}|{$r_arr}))/is"; //数组或对象
echo $reg, "
"; //最终正则表达式
//以下是测试
$str = "
{
"_in"dex" : "log_idx",
"_type" : "test",
"_id" : "1",
"_version" : 1,
"_shards" : {
"total" : 2,
"successful" : 1.3,
"successful0" : -1.3,
"successful2" : 1.3e-3,
"successful4" : 1.3E3,
"failed" : 0
},
"created" : true
}";
preg_match_all($reg, $str, $arr);
print_r($arr);
}
//调用函数执行
json_reg();
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: 使用Ajax完成验证
- 下一篇: Android验证手机号、用户名正则表达式