使用Preg_match_all从字符串中提取关键字/标签

时间:2009-06-24 11:23:07

标签: php regex preg-match-all

我有以下代码

$str = "keyword keyword 'keyword 1 and keyword 2' another 'one more'".'"another keyword" yes,one,two';

preg_match_all('/"[^"]+"|[^"\' ,]+|\'[^\']+\'/', $str, $matches);

echo "<pre>"; print_r($matches); echo "</pre>";

我希望它从字符串中提取关键字,并将它们包含在单引号或双引号中,上面的代码工作正常,但它返回带引号的值。我知道我可以通过str_replace或类似方法删除它们,但我真的想通过preg_match_all函数来解决这个问题。

输出:

Array
(
    [0] => Array
        (
            [0] => keyword
            [1] => keyword
            [2] => 'keyword 1 and keyword 2'
            [3] => another
            [4] => 'one more'
            [5] => "another keyword"
            [6] => yes
            [7] => one
            [8] => two
        )

)

另外,我认为我的正则表达式有点夸张,所以任何更好的建议都会很好:)

非常感谢任何建议/帮助。

4 个答案:

答案 0 :(得分:1)

preg_match_all('/"([^"]+)"|[^"\' ,]+|\'([^\']+)\'/',$str,$matches);

并使用$matches[1]$matches[2]

答案 1 :(得分:1)

你几乎得到了它;你只需要使用lookarounds来匹配引号:

'/(?<=\')[^\'\s][^\']*+(?=\')|(?<=")[^"\s][^"]*+(?=")|[^\'",\s]+/'

答案 2 :(得分:0)

this tokenizeQuote function的评论中查看strtok function

修改您需要修改该功能,因为原始版本仅适用于双引号:

function tokenizeQuoted($string)
{
    for ($tokens=array(), $nextToken=strtok($string, ' '); $nextToken!==false; $nextToken=strtok(' ')) {
        $firstChar = $nextToken{0};
        if ($firstChar === '"' || $firstChar === "'") {
            $nextToken = $nextToken{strlen($nextToken)-1} === $firstChar
                ? substr($nextToken, 1, -1)
                : substr($nextToken, 1) . ' ' . strtok($firstChar);
        }
        $tokens[] = $nextToken;
    }
    return $tokens;
}

编辑也许您应该编写自己的解析器:

$tokens = array();
$buffer = '';
$quote = null;
$len = strlen($str);
for ($i=0; $i<$len; $i++) {
    $char = $str{$i};
    if ($char === '"' || $char === "'") {
        if ($quote === null) {
            if ($buffer !== '') {
                $tokens[] = $buffer;
                $buffer = '';
            }
            $quote = $char;
            continue;
        }
        if ($quote == $char) {
            $tokens[] = $buffer;
            $buffer = '';
            $quote = null;
            continue;
        }
    } else if ($char === ',' || $char === ' ') {
        if ($quote === null) {
            if ($buffer !== '') {
                $tokens[] = $buffer;
                $buffer = '';
            }
            continue;
        }
    }
    $buffer .= $char;
}
if ($buffer !== '') {
    $tokens[] = $buffer;
}

答案 3 :(得分:0)

这需要一个简单的功能来获得你想要的东西,但它有效

preg_match_all('/"([^"]+)"|([^"\' ,]+)|\'([^\']+)\'/',$str,$matches);
function r($str) {
    return str_replace(array('\'','"'), array(''), $str);
}
$a = array_map('r', $matches[0]);
print_r($a);