php - 替换字符串中的嵌套双引号

标签 php regex typography

所以我是一个排版纳粹分子(他们就像打了类固醇的语法纳粹分子),并且我有一个字符串,其中可能包含多级双引号,例如:

$str = 'Outer text "first level "second level "third level" second level" first level" outer text';

在我的母语中,最多三级引用在打印上是正确的,每个级别都有自己的引号。我想替换所有双引号为其相应的实体,例如:

  • 第一级:“文本”( „” )
  • 第 2 级:“文本”( »« )
  • 第三级:“文本”( ’ )
  • 任何其他级别:“文本”( ’ )

所以上面的文本将输出为:

Outer text „first level »second level ’third level’ second level« first level” outer text

此外,可能有 sibling ""字符串中的对:

$str = 'Quote from my book: "She didn\'t feel "depressed", "tired" or "sad"."';

所以这将输出为:

Quote from my book: „She didn't feel »depressed«, »tired« or »sad«.”

(这可能很棘手,但我们知道 " 后面或前面总是有空格 或标点符号 ,.;?! )

最后,$str也可能包含 HTML,其中属性的引号不应更改:

$str = '<p class="quote">The error said: <span class="error_msg">"Please restart your "fancy" computer!"</span></p>';

我听说使用递归正则表达式是一种可能的解决方案,但我正在寻找一种更有效的方法,因为字符串可能是很长的 HTML 文本。

更新:我似乎忽略了 CSS 的 quotes属性(property)和<q>元素。这使得内联引号更加优雅。

最佳答案

试试这个 "#\"(([^()]+|(?R))*)\"#" 是正则表达式递归

样本

class Replace1{
   public $Out,$Depth=0;
   function __construct($Query){
        $this->Depth=0;
        $this->Out=$this->Reaplce($Query);  
   }
   function Reaplce($Query){
      //echo "**********".$Query.$this->Depth."\n";
       $Query = preg_replace_callback("#\"(([^()]+|(?R))*)\"#",function($m){
             $this->Depth++;
             $R=$this->Reaplce($m[1]);
             $this->Depth--;
            return $R;
        },$Query);  
        switch($this->Depth){
          case 0:
             return $Query;
          case 1:
             return '&bdquo;'.$Query.'&rdquo;';
          case 2:
             return '&raquo;'.$Query.'&laquo;'; 
          case 3:
             return '&rsquo;'.$Query.'&rsquo;';  
          default:
             return '&rsquo;'.$Query.'&rsquo;';                     
        }
        return $Query;

  }


}
$obj=new Replace1('Outer text "first level "second level "third level" second level" first level" outer text');
echo $obj->Out;

旧的 PHP

function R($m){
        Replace1::$Depth++;
        $R=Replace1::Reaplce($m[1]);
        Replace1::$Depth--;
        //echo "***".$R.$this->Depth."\n";
        return $R;
}
class Replace1{
public static $Out,$Depth=0;

    function __construct($Query){
    self::$Depth=0;
    self::$Out=self::Reaplce($Query);   
}

static function Reaplce($Query){
    //echo "**********".$Query.$this->Depth."\n";

    $Query = preg_replace_callback("#\"(([^()]+|(?R))*)\"#","R",$Query);
    //echo "**********".$Query.$this->Depth."\n";   
    switch(self::$Depth){
        case 0:
           return $Query;
        case 1:
           return '&bdquo;'.$Query.'&rdquo;';
        case 2:
           return '&raquo;'.$Query.'&laquo;'; 
        case 3:
           return '&rsquo;'.$Query.'&rsquo;';  
        default:
           return '&rsquo;'.$Query.'&rsquo;';         


    }
    return $Query;

}


}
$obj=new Replace1('Outer text "first level "second level "third level" second level" first level" outer text');
echo Replace1::$Out;

输出为

Outer text „first level »second level ’third level’ second level« first level” outer text

html View

Outer text &bdquo;first level &raquo;second level &rsquo;third level&rsquo; second level&laquo; first level&rdquo; outer text

如果删除 echo 注释// 输出将为

 **********Outer text "first level "second level "third level" second level" first level" outer text0
 **********first level "second level "third level" second level" first level1
 **********second level "third level" second level2
 **********third level3
 Outer text &bdquo;first level &raquo;second level &rsquo;third level&rsquo; second level&laquo; first level&rdquo; outer text

关于php - 替换字符串中的嵌套双引号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15877216/

相关文章:

php - 我无法将 IP 添加到我的数据库中。为什么?

javascript - 匹配类中特定结尾之前的任何字符

mysql - mysql中如何统计某个字符串出现的次数

css - 如何简单地控制文本之间的间距

css - 我们不应该只在排版上使用相对的 CSS 单位吗?

php - 如何覆盖/添加到 Laravel 中的密码代理?

php - 预检响应具有无效的 HTTP 状态代码

javascript - 页面加载时深色主题 CSS 问题 1 秒差距

javascript - 为什么我从我的 regex.exec 中得到一个值?

reactjs - Material UI 中的响应式排版?