使用php preg_replace_callback解析句子并忽略括号内的数据

时间:2014-10-27 22:01:46

标签: php preg-replace preg-replace-callback

我有这个字符串,

  

一种有着短毛外套的大型有蹄哺乳动物(Equus caballus)   长长的鬃毛,长尾巴,自古以来就被驯化而且用过   用于骑行以及牵引或搬运货物。

需要转换成这个:

large hoofed mammal(Equus caballus)having short - haired大衣,长长的鬃毛,一条长尾,domesticated since ancient times并用于ridingdrawingcarrying loads

这些是要求:

  1. 长度为5+的单词必须封装在href标签内。 (已经解决了)
  2. 括号内的单词必须被忽略。 这是正则表达式
  3. 中缺少的要求

    目前,下面的代码是将原始字符串转换为此内容(括号内的数据不会被忽略):

    A large hoofed mammalEquus caballushaving一个short - {{3}大衣,长长的鬃毛和长尾haired domesticated since ancient并用于timesriding或{{ 3}} drawing

    这是我目前的代码:

    $result = preg_replace_callback('/\b[\p{L}\p{M}]{5,}\b/u', create_function(
        '$matches',
        'return "<a href=\"http://words.com/".strtolower($matches[0])."\">$matches[0]</a>";'
    ), $data);
    

    如何在同一个正则表达式中实现第二个要求? 谢谢!

1 个答案:

答案 0 :(得分:3)

您可以使用捕获组:

$result = preg_replace_callback('~(\([^)]+\))|[\pL\pM]{5,}~u', function ($m) {
    if (empty($m[1]))
        return '<a href="http://words.com/' . strtolower($m[0]) . '">' . $m[0] . '</a>';
    return $m[1];
}, $data);

或者您可以使用backtracking control verbs (*SKIP)(*FAIL)

$result = preg_replace_callback('~\([^)]+\)(*SKIP)(*FAIL)|[\pL\pM]{5,}~u', function ($m) {
    return '<a href="http://words.com/' . strtolower($m[0]) . '">' . $m[0] . '</a>';
}, $data);