【问题标题】:How to make preg_replace not hungry? [duplicate]如何让 preg_replace 不饿? [复制]
【发布时间】:2019-04-01 12:07:43
【问题描述】:

我有一个字符串:

$str = '{:de}Hallo Welt{:}{:en}Helo world{:}';

现在我需要获取设置语言的子字符串。

$placeholder = '{:en}';
$lang_content =  preg_replace('/(.*)'.preg_quote($placeholder).'(.*)'.preg_quote('{:}').'(.*)/sm', '\2', $str);

如果占位符{:en} 的值我得到Helo world 作为$lang_content 的值,它工作正常,但如果{:de} 我得到Hallo Welt{:}{:en}Helo world。 如何修复?谢谢!

【问题讨论】:

  • 在正则表达式语言中称为lazy?

标签: php regex preg-replace


【解决方案1】:

使用 Ungreedy 标志 (U)。

您可以将正则表达式末尾的标志从 /sm 更新为 /smU,以使结果在字符串中下一次出现 {:} 时停止,而不是在最后一次出现。

如果字符串要包含多次出现,也许您还可以添加全局 (g) 标志,这样正则表达式就不会在第一次出现之后停止。

你可以在这里测试它:https://regex101.com/r/4XSPoz/3

顺便说一句,您似乎正在使用 preg_replace 作为查找子字符串的一种方式,并且实际上不需要在结果中替换它,也许您应该改用 preg_match

【讨论】:

    【解决方案2】:

    您需要通过在第二次捕获中添加? 来使正则表达式变得惰性。

    $str = '{:de}Hallo Welt{:}{:en}Helo world{:}';
    
    $placeholder = '{:de}';
    $lang_content =  preg_replace('/(.*)'.preg_quote($placeholder).'(.*?)'.preg_quote('{:}').'(.*)/sm', '\2', $str);
    
    echo $lang_content; // Hallo Welt
    

    https://3v4l.org/m6AGF


    一种可选方法是使用 preg_match 来获取关联数组。

    $str = '{:de}Hallo Welt{:}{:en}Helo world{:}';
    
    preg_match_all("/\{:(.*?)}(.*?)\{/", $str, $matches);
    $matches = array_combine($matches[1], $matches[2]);
    
    var_dump($matches);
    echo $matches["de"]; // Hallo Welt
    

    https://3v4l.org/ELB2B

    【讨论】:

    • 非常感谢!它工作正常。
    猜你喜欢
    • 2016-10-30
    • 2014-12-16
    • 1970-01-01
    • 1970-01-01
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多