preg_replace上的PHP崩溃

preg_replace上的PHP崩溃,php,crash,preg-match,Php,Crash,Preg Match,我使用php.exe运行了以下脚本: preg_replace('#(?:^[^\pL]*)|(?:[^\pL]*$)#u','',$string); 或其等效物: preg_replace('#(?:^[^\pL]*|[^\pL]*$)#u','',$string); 如果$string=“S”或$string=“ذذ”它工作,如果string='ذ'它产生�这是不正确的,如果string='ذذ'PHP崩溃 但是它在4.4.0-4.4.9、5.0.5-5.1.6版本中工作 怎么了 见:

我使用
php.exe
运行了以下脚本:

preg_replace('#(?:^[^\pL]*)|(?:[^\pL]*$)#u','',$string);
或其等效物:

preg_replace('#(?:^[^\pL]*|[^\pL]*$)#u','',$string);
如果
$string=“S”
$string=“ذذ”
它工作,如果
string='ذ'
它产生
这是不正确的,如果
string='ذذ'
PHP崩溃

但是它在4.4.0-4.4.9、5.0.5-5.1.6版本中工作

怎么了


5.2.0-5.3.22和5.5.0 Beta1的输出

4.4.0-4.4.9、5.0.5-5.1.6的输出

دد 
4.3.11、5.0.0-5.0.4的输出

Warning: preg_replace(): Compilation failed: PCRE does not support \L, \l, \N, \P, \p, \U, \u, or \X at offset 7 in /in/T3rpV on line 3 
4.3.0-4.3.10的输出

Warning: Compilation failed: PCRE does not support \L, \l, \N, \P, \p, \U, \u, or \X at offset 7 in /in/T3rpV on line 3

您可以使用可选的mb_ereg_replace()函数:

mb_internal_encoding("UTF-8");
mb_regex_encoding("UTF-8");
echo mb_ereg_replace('#(?:^[^\pL]*)|(?:[^\pL]*$)#u','',$string);
也许这会有帮助:

这些属性通常仅在使用编译PCRE时可用 “--启用unicode属性”


使用
preg_quote
,在将特殊字符与正则表达式一起使用之前,必须正确转义它。例如:

<?php
$string = preg_quote("\دد");
echo preg_replace('#(?:^[^\pL]*)|(?:[^\pL]*$)#u','',$string);

从表达式本身来看,有两件事可以改进:


  • *
    乘法器不是很有用;为什么要用空字符串替换可能为空的匹配项?事实上,在我的系统上运行此操作会从
    preg_replace()
    操作中产生
    NULL

  • 内存组可以合并在一起

  • 这是应用两种改进后的代码:

    $string = 'ﺫﺫ';
    var_dump(preg_replace('#(?:^[^\pL]+|[^\pL]+$)#u', '', $string));
    // string(4) "ﺫﺫ"
    

    如果您只是在寻找多字节微调功能(从4.3.0开始支持):


    最后,这个错误被解决了:


    它在这里也崩溃了。PHP5.4.7。我可以确认,最新的测试版PHP5.5.0beta2(3月28日发布)也会崩溃@ComFreek我的答案也会让它崩溃吗?不,不是你可以,你的正则表达式的行为完全不同,也不等同于我的。Try:
    $string='.d.
    应将正则表达式重新格式化为POSIX语法。另外,我不确定它是否支持POSIX正则表达式字符,并且对于普通字符不是必需的。但偶数
    echo preg_替换(“#(?:^[^\pL]*.[^\pL]*$)#u',”,preg_quote(“žذذ”)崩溃<代码>预报价(“预报价”)
    是另一个字符串。
    \\ss
    可能您误解了
    preg_quote()
    的用途,它是用来转义正则表达式中使用的特殊字符:)别提它;至少我能为以前的同事做点什么,呵呵。@Jack请参考php.net/manual/en/function.preg-quote.php并重新阅读这个问题。谢谢。如果这些属性不可用,PHP将发出警告而不是崩溃。根据我自己的经验,
    b(任何单词边界字符)不使用西里尔字母符号时,我经历了一段艰难的时期,它只是忽略了它们,而另一方面,按照拉丁语的预期工作。我不得不使用类似于
    $boundL='(^ |[-\s\.>“事实上,在我的系统上运行这个会产生NULL”哇!实际上你发现了另一个bug:@PHPst看起来像:)我的答案中的代码有帮助吗?@Jack它没有崩溃,但它输出了
    字符串(6)”ﺫﺫ"而不是您预期的结果。@ComFreek以字节为单位的长度说明不了多少,但不确定为什么两个字符各占3个字节。@Phpst我理解。我将在bugs.php.net报告一个错误,并参考此问题。
    
    <?php
    $string = preg_quote("\دد");
    echo preg_replace('#(?:^[^\pL]*)|(?:[^\pL]*$)#u','',$string);
    
    $string = 'ﺫﺫ';
    var_dump(preg_replace('#(?:^[^\pL]+|[^\pL]+$)#u', '', $string));
    // string(4) "ﺫﺫ"
    
    $string=' دد';
    var_dump(preg_replace('#(?:^\s+|\s+$)#u', '', $string));
    
    Output for 4.4.0 - 4.4.9, 5.0.5 - 5.1.6, 5.5.27 - 5.5.33, 5.6.11 - 7.0.4, hhvm-3.6.1 - 3.12.0
        دد