php - 正则表达式模式而不是爆炸
问题描述
我有这样的文字:
NodeName:
nd1,
nd2
;
SqlData:
{code:java}
select id, regexp_replace(username, '[;]+'::text, ','::text, 'g'::text) from users where id =1
{code}
{code:java}
select username from users where id =1
{code}
;
SqlFiles:
{code:java}
select filename || ';'::text from users where id =1
{code}
;
哪里可以是新行,行之间的空格等。我想用';'分隔这个字符串 符号以获取以下字符串(没有结束行和空格):
NodeName:nd1,nd2
------
SqlData:{code:java}select id, regexp_replace(username, '[;]+'::text, ','::text, 'g'::text) from users where id =1{code}{code:java}select username from users where id =1{code}
------
SqlFiles:{code:java}select filename || ';'::text from users where id =1{code}
我不能简单地使用explode
这样的功能:
$res = explode(';', $str);
因为';'
可以在代码标签里面的SQL查询中使用。
所以我看到的唯一方法是使用preg_match_all
一些模式。
我用
preg_match_all('\(?s)(?<=\{code:java\}).*?(?=\{code\})|.*?;\', $str, $res);
但它仍然返回 5 个匹配而不是 3 个。
任何想法如何纠正模式以使其工作?
解决方案
您可以使用更具体的模式来匹配不同的部分并删除换行符。
您可以使用负前瞻来排除以不允许的模式开头的匹配行,并防止匹配停止在{code:java}
后面不跟;
^(?:NodeName:\h*(?:\R(?!\h*;$).*)*|Sql(?:Data|Files):\h*\R+{code:java}(?:\R(?!{code}\R\h*;$).*)*\R{code})(?=\R+\h*;$)
^
字符串的开始(?:
轮换的非捕获组|
NodeName:\h*
匹配NodeName:和可选的水平空白字符(?:\R(?!\h*;$).*)*
重复匹配所有不以可选空格开头和;
字符串末尾的行|
或者Sql(?:Data|Files):\h*
匹配SqlData:或SqlFiles:以及可选空格\R+{code:java}
匹配换行符和{code:java}(?:\R(?!{code}\R\h*;$).*)*
重复匹配所有不以{code}开头的行,后跟换行符,并;
在字符串的末尾\R{code}
匹配换行符和{code}
)
关闭非捕获组(?=\R+\h*;$)
正向前瞻,断言 1+ 换行符,可选的 whitspace 字符和;
右侧字符串的末尾
示例代码$str
示例字符串在哪里。
$re = '/^(?:NodeName:\h*(?:\R(?!\h*;$).*)*|Sql(?:Data|Files):\h*\R+{code:java}(?:\R(?!{code}\R\h*;$).*)*\R{code})(?=\R+\h*;$)/m';
preg_match_all($re, $str, $matches);
$result = array_map(function($x){
return preg_replace("/\R+/", "", $x);
}, $matches[0]);
print_r($result);
输出
Array
(
[0] => NodeName: nd1, nd2
[1] => SqlData: {code:java} select id, regexp_replace(username, '[;]+'::text, ','::text, 'g'::text) from users where id =1{code} {code:java} select username from users where id =1{code}
[2] => SqlFiles:{code:java} select filename || ';'::text from users where id =1{code}
)
推荐阅读
- sql - 将变量作为参数传递给 varchar(),如 cast(column1 as varchar(@variable))
- java - Spring Cloud PubSub 无法发布到队列
- sql - ADD COLUMN 查询中 COLUMN 附近的语法不正确
- algorithm - 何时何地使用哪种渐近符号
- javascript - 如何从回调函数的外部范围使用变量
- python - 用python从json文件中读取元素
- python - 我的脚本运行一次,如何将其编码为始终运行?
- pandoc - 生成 HTML 时在 Pandoc 中按年份组织引用
- debezium - 以 ISO-8601 格式返回日期 - Debezium/Postgres 插件
- apache-kafka - 使用 kafka 进行 CQRS