preg_match将特殊字符视为一个单独的单词

问题描述 投票:0回答:1

我有一个正则表达式,用于以包含关键字(关键字基于模式,例如{query:ABCD:1234})的方式截断字符串,在关键字之前5个单词,在关键字之后5个单词。然后在该关键字之前和之后,我将显示三个点,例如:

Lorem ipsum dolor sit amet, consectetur {query:ABCD:1234} adipiscing elit. Mauris consequat, quam id feugiat varius.

我希望:

... ipsum dolor sit amet, consectetur {query:ABCD:1234} adipiscing elit. Mauris consequat, quam ...

这里是正则表达式:

preg_match("/((?:\w+\W+){5})" . preg_quote($keyword, "/") . "((?:\W+\w+){5})/", $text, $matches);

问题是当最后一个单词附加到点/问号/感叹号时,此正则表达式不起作用,例如:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris consequat, quam id feugiat varius {query:ABCD:1234}.

我希望

... quam id feugiat varius {query:ABCD:1234}.

但返回:

... quam id feugiat varius {query:ABCD:1234}

((末尾没有点。)

当最后一个单词不是关键字时也是一样:

Original: {query:ABCD:1234} Lorem ipsum dolor sit amet!
Returns: {query:ABCD:1234} Lorem ipsum dolor sit amet ...
Expected: {query:ABCD:1234} Lorem ipsum dolor sit amet!

如何解决?

更新:

这是我的代码:

    function cutMessage($text, $search)
{
    $pieces = explode(' ', $text);
    $firstWord = $pieces[0];
    $lastWord = array_pop($pieces);

    preg_match("/((?:\w+\W+){0,5})" . preg_quote($search, "/") . "((?:\W+\w+){0,5})/", $text, $matches);

    $returnText = '';

    $pieces = explode(' ', $matches[1]);
    if (!empty($matches[1]) && $pieces[0] != $firstWord) {
        $returnText .= '... ' . $matches[1];
    } elseif (!empty($matches[1])) {
        $returnText .= $matches[1];
    }

    $returnText .= $search;

    $pieces = explode(' ', $matches[2]);
    if (!empty($matches[2]) && array_pop($pieces) != $lastWord) {
        $returnText .= $matches[2] . ' ...';
    } elseif (!empty($matches[2])) {
        $returnText .= $matches[2];
    }
    return $returnText;
}
regex string preg-match
1个回答
0
投票

如果使用示例关键字回显当前模式,则(?:\W+\w+){0,5}末尾的该部分与逗号或感叹号不匹配,因为\w+与1个或多个单词字符匹配。

((?:\w+\W+){0,5})\{query\:ABCD\:1234\}((?:\W+\w+){0,5})
                                              ^^

一个选项是将第三个捕获组([!.]?)中允许匹配的任何非单词字符匹配0倍以上>

((?:\w+\W+){0,5})\{query\:ABCD\:1234\}((?:\W+\w+){0,5})([!.]?)
                                                       ^^^^^^^

当您检查捕获组的值是否不为空时,您可以为第三捕获组添加另一项检查。

如果该组不为空,则连接组2和组3。

if (!empty($matches[3])) {
    $returnText .= $matches[2] . $matches[3];
} elseif (!empty($matches[2]) && array_pop($pieces) != $lastWord) {
    $returnText .= $matches[2] . ' ...';
} elseif (!empty($matches[2])) {
    $returnText .= $matches[2];
}
return $returnText;

Regex demo | Php demo

© www.soinside.com 2019 - 2024. All rights reserved.