【问题标题】:PHP Preg Match, get value between specific patternPHP Preg Match,获取特定模式之间的值
【发布时间】:2016-01-15 04:52:19
【问题描述】:

我有一个 php 应用程序,它在数据库中保存以下输出:

::cck_gx::gx::/cck_gx::
::i1|0|gx::Lorem::/i1|0|gx::
::head1|0|gx::ipsum::/head1|0|gx::
::tx1|0|gx::dolor, fithos lusec.::/tx1|0|gx::
::cckend_gx::::/cckend_gx::
::cck_gx::gx::/cck_gx::
::i1|1|gx::calendar::/i1|1|gx::
::head1|1|gx::1 Fatura Grátis Por Ano::/head1|1|gx::
::tx1|1|gx::10% de cada mensalidade é reservado, e o valor acumulado até a renovação do Seguro Porto Seguro ou Azul Seguros, é devolvido em forma de desconto. Ou seja, Cliente Conecta pode ter uma fatura de celular grátis por ano.::/tx1|1|gx::

我想使用 preg_match 从此输出中检索信息。例如,在下面的示例中检索“Lorem”和“ipsum”相同位置的任何值:

::i1|0|gx::Lorem::/i1|0|gx::
::head1|0|gx::ipsum::/head1|0|gx::

但我对 preg_match 语法一无所知。

我知道我需要为每个“标签”使用不同的 preg 匹配(例如用于检索所有“i1”值的 preg_match,用于检索所有“head1”的不同 preg_match 等等)。我只需要一个可以理解正确模式的示例。

另外,最后一行是一个示例,其中包含许多不同的字符,如数字、逗号、“%”等,我不确定这是否会混淆语法。

这是我失败的两次尝试:

preg_match('~[::i1|0|gx::](.*?)[/::i1|0|gx::]~', $maindata->introtext, $match1a);
 preg_match('::i1|0|gx::(.*?)::/i1|0|gx::', $maindata->introtext, $match1a);
 preg_match('/::i1|0|gx::(.*?)::.i1|0|gx::/', $maindata->introtext, $match1a);

【问题讨论】:

  • |s 需要转义。我认为[: 被视为 POSIX 字符类。您是否也尝试与这些进行分组?尝试在 regex101 之类的网站上运行您的正则表达式。

标签: php regex preg-match


【解决方案1】:

希望这会有所帮助

<?php
    $str = '::i1|0|gx::Lorem::/i1|0|gx::';
    preg_match('/(?<=gx::).*(?=::\/)/', $str);

你也可以使用preg_match_all()

<?php
    $str = '::cck_gx::gx::/cck_gx::
    ::i1|0|gx::Lorem::/i1|0|gx::
    ::head1|0|gx::ipsum::/head1|0|gx::
    ::tx1|0|gx::dolor, fithos lusec.::/tx1|0|gx::
    ::cckend_gx::::/cckend_gx::
    ::cck_gx::gx::/cck_gx::
    ::i1|1|gx::calendar::/i1|1|gx::
    ::head1|1|gx::1 Fatura Grátis Por Ano::/head1|1|gx::';

    preg_match_all('/(?<=gx::).*(?=::\/)/', $str, $matches);
    var_dump($matches);

(?&lt;=gx::) Positive Lookbehind - 断言下面的正则表达式可以匹配

. 匹配任何字符(换行符除外)

* 在零次和无限次之间,尽可能多次

(?=::\/) Positive Lookahead - 断言下面的正则表达式可以匹配

:: 匹配字符 :: 字面意思

\/ 匹配字符 / 字面意思

【讨论】:

  • 谢谢,这很有帮助;
【解决方案2】:

你可以想出以下正则表达式:

::(\w+)[^::]+::(?<content>.*?)::(?=\/\1)

PHP 代码 sn-p 和 freespacing 模式下的正则表达式解释如下所示。请参阅example for it on regex101

<?php
$string = '
::cck_gx::gx::/cck_gx::
::i1|0|gx::Lorem::/i1|0|gx::
::head1|0|gx::ipsum::/head1|0|gx::
::tx1|0|gx::dolor, fithos lusec.::/tx1|0|gx::
::cckend_gx::::/cckend_gx::
::cck_gx::gx::/cck_gx::
::i1|1|gx::calendar::/i1|1|gx::
::head1|1|gx::1 Fatura Grátis Por Ano::/head1|1|gx::
';

$regex = '~
        ::
        (\w+)
        # tag 
        [^:]+::
        # match everything except a colon, then two colons 
        (?<content>.*?)
        # match everything lazily and capture it in a group called content
        ::
        # two colons 
        (?=\/\1)
        # closing tag with tag captured in group 1
        ~x';
preg_match_all($regex, $string, $matches);
print_r($matches["content"]);
/* output:
Array
(
    [0] => gx
    [1] => Lorem
    [2] => ipsum
    [3] => dolor, fithos lusec.
    [4] => 
    [5] => gx
    [6] => calendar
    [7] => 1 Fatura Grátis Por Ano
)
*/
?>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多