【问题标题】:PHP pattern matching alternate numbersPHP 模式匹配备用数字
【发布时间】:2015-11-09 03:51:44
【问题描述】:

如何在 PHP 中计算匹配 [] 或 [7] 的模式?

我需要匹配不同字符串中的特定模式,如下例所示:

Lorem ipsum dolor sit amet, consectetur [] adipiscing elit. Phasellus quis lectus metus, at posuere neque.

Lorem ipsum dolor sit amet, consectetur [23] adipiscing elit. Phasellus quis lectus metus, at posuere neque. Sed pharetra nibh [24] eget orci convallis at posuere leo convallis. Sed blandit augue [25] vitae augue scelerisque bibendum. Vivamus sit amet libero turpis, non venenatis urna. In blandit, odio convallis suscipit venenatis, ante ipsum cursus [26] augue.

在第一个例子中,空的 [] 表示需要匹配模式和替换字符串的单个点。

第二个示例有数字表示多个唯一点,在这些点上,字符串需要匹配并替换为唯一内容。

我使用以下代码成功匹配第一个示例:

preg_replace('[]', $replacement, $fulltext);

但是,我不确定如何匹配要处理的其他文本的不同数字。

【问题讨论】:

    标签: php pattern-matching


    【解决方案1】:

    您的解决方案只是用可选数字进行 preg 替换

    preg_replace('/\[\d*\]/', $replacement, $fulltext);
    

    【讨论】:

    • 你明白你的括号在这里被视为delimiters,对吧?意思是,这与说preg_replace('/\d*/', $replacement, $fulltext); 没有什么不同
    • 您转义了括号,这是正确的,但请注意这仍然无效,因为您仍然没有分隔符。表达式是正确的,您仍然需要分隔符,否则 preg_replace 将失败并返回 Delimiter must not be alphanumeric or backslash 错误。如果在答案中得到解决,我会投票。
    【解决方案2】:

    TL;DR;

    您不需要preg_replace。请改用str_replace

    更详细的解释见下文。


    注意括号[]PCRE syntax 中具有特殊含义可能很重要,因为它们表示character classes。这意味着您的模式可能没有按照您期望的那样做。

    例如

    preg_replace('[]', 'foo', 'Lorem ipsum dolor sit amet, consectetur [] adipiscing elit. Phasellus quis lectus metus, at posuere neque.')
    

    会给你

    "fooLfooofoorfooefoomfoo fooifoopfoosfooufoomfoo foodfooofoolfooofoorfoo foosfooifootfoo fooafoomfooefootfoo,foo foocfooofoonfoosfooefoocfootfooefootfooufoorfoo foo[foo]foo fooafoodfooifoopfooifoosfoocfooifoonfoogfoo fooefoolfooifootfoo.foo fooPfoohfooafoosfooefoolfoolfooufoosfoo fooqfooufooifoosfoo foolfooefoocfootfooufoosfoo foomfooefootfooufoosfoo,foo fooafootfoo foopfooofoosfooufooefoorfooefoo foonfooefooqfooufooefoo.foo"
    

    这根本不是你想要的。

    这是因为 PCRE 还需要 delimiters 包围模式。在这里,括号将被视为分隔符,您最终会得到一个空模式。

    也可以使用括号样式的分隔符,其中开始和结束括号分别是开始和结束分隔符。 (){}[]<> 都是有效的括号样式分隔符对。

    你应该使用

    preg_replace('/\[\d*\]/', $replacement, $fulltext);
    

    这将使用 \ 反斜杠字符转义括号,并提供可选数量的数字字符以落入模式匹配表达式。

    如果您希望替换字符串位于括号内而不是替换实际的括号,您可以将模式括在圆括号中并使用back references 进行替换。

    如果您想将特定模式与特定替换字符串匹配(模式比简单的子字符串搜索/替换更复杂),那么您应该改用preg_replace_callback_array但是,需要注意的是,此功能仅在 PHP 7 中可用

    示例

    $newText = preg_replace_callback_array(
                   [
                       '/\[(23)\]/' => function ($match) {
                           return 'foo';
                       },
                       '/\[(24)\]/' => function ($match) {
                           return 'bar';
                       },
                   ],
                   $fulltext
               );
    

    这会给你类似......

    "Lorem ipsum dolor sit amet, consectetur foo adipiscing elit. Phasellus quis lectus metus, at posuere neque. Sed pharetra nibh bar eget orci convallis at posuere leo convallis. Sed blandit augue [25] vitae augue scelerisque bibendum. Vivamus sit amet libero turpis, non venenatis urna. In blandit, odio convallis suscipit venenatis, ante ipsum cursus [26] augue."
    

    如果您真正需要的是基于子字符串搜索进行替换(例如 [23] 将被替换为字符串 'foo' 而 [24] 将被替换为字符串 'bar' 等...)那么你不需要正则表达式。相反,您可以为此使用str_replace

    这是一个例子......

    $fulltext = 'Lorem ipsum dolor sit amet, consectetur [23] adipiscing elit. Phasellus quis lectus metus, at posuere neque. Sed pharetra nibh [24] eget orci convallis at posuere leo convallis. Sed blandit augue [25] vitae augue scelerisque bibendum. Vivamus sit amet libero turpis, non venenatis urna. In blandit, odio convallis suscipit venenatis, ante ipsum cursus [26] augue.';
    $searchStrings = [
                      '[23]',
                      '[24]',
                      '[25]',
                      '[26]',
                     ];
    $replacements  = [
                      '[foo]',
                      '[bar]',
                      '[baz]',
                      '[quix]',
                     ];
    $newText = str_replace($searchStrings, $replacements, $fulltext);
    

    这给了你

    "Lorem ipsum dolor sit amet, consectetur [foo] adipiscing elit. Phasellus quis lectus metus, at posuere neque. Sed pharetra nibh [bar] eget orci convallis at posuere leo convallis. Sed blandit augue [baz] vitae augue scelerisque bibendum. Vivamus sit amet libero turpis, non venenatis urna. In blandit, odio convallis suscipit venenatis, ante ipsum cursus [quix] augue."
    

    【讨论】:

    • preg_replace('/\[\d*\]+/', $replacement, $fulltext); 也是错误的......它将匹配任意数量的右括号
    • 你是对的。我不知道+ 是怎么溜进去的。已修复,谢谢:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    • 2012-10-19
    相关资源
    最近更新 更多