所以我是一个排版 - 纳粹(他们就像类固醇的语法 - 纳粹),我有一个字符串,可能包含多级双引号,例如:
$str = 'Outer text "first level "second level "third level" second level" first level" outer text';
以我的母语,最多三个级别的引用在印刷上是正确的,每个级别都有自己的引号。我想替换所有双引号对到相应的实体,这样:
„
和”
)»
和«
)’
)’
)所以上面的文字将输出为:
外部文本“第一级”第二级“第三级”第二级“第一级”外部文本
此外,字符串中可能存在兄弟""
对:
$str = 'Quote from my book: "She didn\'t feel "depressed", "tired" or "sad"."';
所以这将输出为:
从我的书中引用:“她感觉不舒服”,“累了”或“悲伤”。“
(这可能很棘手,但我们知道"
始终跟随或前面有空格,或标点符号
,
,.
,{{1} },;
,?
)
最后,!
也可能包含HTML,其中不应更改属性的引号:
$str
我听说使用 recursive regexp 是一种可行的解决方案,但我正在寻找更强大的有效方式,因为字符串可能是长HTML文本。< / p>
更新: 我似乎滑过了CSS的$str = '<p class="quote">The error said: <span class="error_msg">"Please restart your "fancy" computer!"</span></p>';
属性和quotes
元素。这使得内联引号更加优雅。
答案 0 :(得分:1)
试试这个"#\"(([^()]+|(?R))*)\"#"
是regex recursive
样品
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 '„'.$Query.'”';
case 2:
return '»'.$Query.'«';
case 3:
return '’'.$Query.'’';
default:
return '’'.$Query.'’';
}
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 '„'.$Query.'”';
case 2:
return '»'.$Query.'«';
case 3:
return '’'.$Query.'’';
default:
return '’'.$Query.'’';
}
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视图
Outer text „first level »second level ’third level’ second level« first level” outer text
如果删除echo comment //
,则输出将为
**********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 „first level »second level ’third level’ second level« first level” outer text
答案 1 :(得分:1)
解析HTML来做这种智能引用即使不是不可能,也是一项非常棘手的任务。
我有构建JoliTypo,它使用DOM加载器(\DomDocument
),并处理所有文本字符串以对其应用一些排版修复:EnglishQuotes是其中之一,但它只处理第一级此时此刻。在法语中我们也有不同的引号层次结构,所以它肯定在我的待办事项列表中。
虽然@mohammad解决方案适用于简单的字符串,但与JoliTypo相结合,您可能有机会以可靠的方式获得您想要的大型HTML文档。
我可以询问在哪种语言环境中使用这种引用(Outer text „first level »second level ’third level’ second level« first level” outer text
)?