php - preg_match_all - 从模板中提取键/值

标签 php regex preg-match-all

我将以下内容存储在 mysql 数据库中:

%URL% https://google.com
%TEXT% Hello world!
%LARGETEXT% Hello
My name is ...
I am from ...

我的目标是让 % 包裹的字符串成为 PHP 数组的键,除此之外的字符串就是值。

问题是,我的正则表达式没有提取多行字符串。

这是代码:

preg_match_all ("/%(\w+)%(.*)/", $msg, $matches);

它确实输出:

  [1]=>
  array(3) {
    [0]=>
    string(5) "BASIC"
    [1]=>
    string(4) "TEXT"
    [2]=>
    string(9) "LARGETEXT"
  }
  [2]=>
  array(3) {
    [0]=>
    string(18) " https://google.de"
    [1]=>
    string(13) " Hello world!"
    [2]=>
    string(6) " Hello"
  }

在第二个数组中仅显示“Hello”,而不是:

Hello
My name is ...   
I am from ...

我尝试了各种正则表达式,但总是得到相同的结果。

最佳答案

您可以使用

~%(\w+)%(.*?)(?=%\w+%|$)~s

请参阅regex demo

详细信息

  • % - 百分号
  • (\w+) - 第 1 组:一个或多个单词字符
  • % - 百分号
  • (.*?) - 第 2 组:任何 0+ 个字符(请注意,s 修饰符将使 . 匹配换行符,也)尽可能少,直到第一次出现...
  • (?=%\w+%|$) - %,1+ 个单词字符,% 或字符串结尾。<

一个相同的展开表达式(更有效的一个)看起来像

~%(\w+)%([^%]*(?:%(?!\w+%)[^%]*)*)~

(不需要 s 修饰符)。请参阅regex demo .

[^%]*(?:%(?!\w+%)[^%]*)* 匹配 % 之外的任何 0+ 个字符,然后匹配 0 个或多个后续出现的 %,后跟不带 1 个以上单词字符,然后 % 后跟除 % 之外的任何 0+ 个字符.

如果您的条目始终出现在不同行的开头,您可以使用

~^%(\w+)%(.*?)(?=^%\w+%|\z)~sm

查看此regex demo

详细信息

  • ^ - 匹配的开头(由于m修饰符)
  • %(\w+)% - 匹配 %,然后将一个或多个单词字符匹配并捕获到第 1 组中,然后匹配 %
  • (.*?) - 将尽可能少的任意 0+ 个字符匹配并捕获到第 2 组中,直到第一次出现...
  • (?=^%\w+%|\z) - 行首,%,1+ 个单词字符,%或者字符串的最末尾(\z 可能会替换为 \Z,因为只需字符串位置的末尾就足够了)。

展开版本:

~^%(\w+)%(.*(?:\R(?!%\w+%).*)*)~m

参见another demo(.*(?:\R(?!%\w+%).*)*) 部分将以下内容匹配到第 2 组:

  • .* - % 之后的行的其余部分,1+ 个单词字符,% 子字符串
  • (?:\R(?!%\w+%).*)* - 匹配 0 次以上连续出现的以下内容:
    • \R(?!%\w+%) - 没有 % 的换行序列 (\R),1+单词字符和后面的 % 然后...
    • .* - 除换行符之外的任何 0+ 个字符,尽可能多,直到行尾。

关于php - preg_match_all - 从模板中提取键/值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45698546/

相关文章:

php - 使用 Xpath 和数据属性提取内容

php - 可以为库代码而不是我的代码关闭 E_STRICT?

ruby-on-rails - 为什么正则表达式不能匹配@符号?

regex - 使用命名子表达式时是否可以复制 %+ 哈希?

php - 将新的命名键添加到 preg_match_all 的匹配项中

PHP 函数到 Javascript : scan string and add words in array

php - 检测内容是否在 codeigniter 中的 php 文件中的一行之前发送

php - mysql在PHP中选择不同的查询

regex - 如何删除不在我本地存储库中的远程标签?

php preg_match_all 匹配错误的字符串