替换字符串的所有出现

时间:2016-06-12 20:01:18

标签: php preg-replace

我想为包含阿拉伯语文本的所有p标记添加一个类。例如:

<p>لمبارة وذ</p> 
<p>do nothing</p> 
<p>خمس دقائق يخ</p> 
<p>مراعاة إبقاء 3 لاعبين</p>

应该成为

<p class="foo">لمبارة وذ</p> 
<p>do nothing</p>
<p class="foo">خمس دقائق يخ</p> 
<p class="foo">مراعاة إبقاء 3 لاعبين</p>

我正在尝试使用PHP preg_replace函数将模式(阿拉伯语)与以下表达式匹配:

preg_replace("~(\p{Arabic})~u", "<p class=\"foo\">$1", $string, 1);

然而它无法正常工作。它有两个问题

  1. 它只匹配第一段。
  2. 添加空<p>
  3. 沙箱Link

3 个答案:

答案 0 :(得分:3)

  

它只匹配第一段。

这是因为您添加了最后一个参数,表示您只想替换第一个匹配项。把这个论点留下来。

  

添加空<p>

这实际上是你不匹配的原始<p>。只需将其添加到匹配模式中,但将其保留在匹配组之外,因此当您使用$1替换时,它将被忽略。

以下是更正版本,也在sandbox上:

$text = preg_replace("~<p>(\p{Arabic}+)~u", "<p class=\"foo\">$1", $string);

答案 1 :(得分:2)

你的第一个问题是你并没有告诉它与<p>匹配,所以它没有。

你的主要问题是空间不是阿拉伯语。只需添加匹配它们的替代方案即可解决您的问题:

$text = preg_replace("~<p>(\p{Arabic}*|\s*)~u", "<p class=\"foo\">$1", $string);

答案 2 :(得分:2)

使用DOMDocument和DOMXPath:

$html = <<<'EOD'
<p>لمبارة وذ</p> 
<p>خمس دقائق يخ</p> 
<p>مراعاة إبقاء 3 لاعبين</p>
EOD;

libxml_use_internal_errors(true);

$dom = new DOMDocument;
$dom->loadHTML('<div>'.$html.'</div>', LIBXML_HTML_NOIMPLIED);

$xpath = new DOMXPath($dom);

// here you register the php namespace and the preg_match function
// to be able to use it in the XPath query
$xpath->registerNamespace("php", "http://php.net/xpath");
$xpath->registerPhpFunctions('preg_match');

// select only p nodes with at least one arabic letter
$pNodes = $xpath->query("//p[php:functionString('preg_match', '~\p{Arabic}~u', .) > 0]");

foreach ($pNodes as $pNode) {
    $pNode->setAttribute('class', 'foo');
}

$result = '';
foreach ($dom->documentElement->childNodes as $childNode) {
    $result .= $dom->saveHTML($childNode);
}

echo $result;