1

我需要检测文本中用空格分隔的单词。例如我的文字是:

some parent +kid -control "human right" world

现在我需要检测一些父母世界。(之前和之后没有 + - ( ) < > 的所有单词,引号内的所有单词都必须丢弃)所以我用以下方式编写这个正则表达式preg_match_all()

(?:^|[\s]+)((?:(?![\+\(\)\<\>\s\-\"]).)+)(?:[\s]+|$)

但它只检测到一些世界。我该如何解决?

编辑

我也需要它用于Javascript。但它似乎不适用于 Javascript。我怎么能用javascript做到这一点?

编辑

我找到了一个解决方案,但它似乎很愚蠢。你的想法是什么?

$str = 'some parent +kid -control "my human right" world';
$words=array();
$quot=false;
$discard=false;
$word='';
for($i=0;$i<=strlen($str);$i++){
    $chr=substr($str,$i,1);
    if($chr=='"'){
        if($quot){
            $quot=false;
        }else{
            $quot=true;
        }
        continue;
    }
    if($quot)continue;
    if($chr==' '||$i==strlen($str)){
        if(strlen($word)&&!$discard)$words[]=$word;
        $discard=false;
        $word='';
        continue;
    }elseif(in_array($chr,array('+','-','(',')','<','>'))){
        $discard=true;
        continue;
    }
    $word.=$chr;
}
print_r($words);//Array ( [0] => some [1] => parent [2] => world ) 

编辑 PHP 的最终方式(这是用于多语言查询)(特别感谢橡胶靴):

$query='some parent +kid -control "my human right" world';
$result=array();
if(preg_match_all('/(?:"[^"]+")|(?:^|[\s])(?P<q>(?:(?![\+\(\)\<\>\s\-\"]).)+)/',$query,$match)){
    $result=array_filter($match['q'],'strlen');
}
print_r($result);// some,parent,world

javascript的最终方式(这是用于多语言查询)(特别感谢橡胶靴):

var query='some parent +kid -control "my human right" world';
var result=Array();
var tmp;
var patt=RegExp('(?:"[^"]+")|(?:(?:^|\\s)((?:(?![\\+\\(\\)\\<\\>\\s\\-\\"]).)+))', 'g');
while(tmp = patt.exec(query)){
    if(typeof(tmp[1])!=='undefined') result.push(tmp[1]);
}
alert(result);// some,parent,world
4

2 回答 2

1

尝试:

$str = 'some parent +kid -control "human right" world';
$words = array_filter(explode(' ', $str), function($word) {
    return preg_match('/^[^-+"]*$/', $word);
});
echo implode(', ', $words); //some, parent, world

这不允许任何包含+,-或的词"。这是你的意思吗?

注意我使用匿名函数作为回调到array_filter(). 如果您使用的是 PHP < 5.3,请改用命名函数,或者使用create_function().

于 2012-07-30T12:29:23.787 回答
1

如果给出以下字符串:

 $t ='some parent +kid -control "human huhu right" world';

也可以使用相当简单的表达式根据您的规范提取单词:

 $r = '/ (?:" [^"]+ ")? \s?
         (?<!\S) \b (\w+)
       /x';
 preg_match_all($r, $t, $matches);

这导致:

foreach($matches[1] as $m) echo $m . "\n";

some
parent
world

使用的技术:

expr(?:" [^"]+ ")?使用引号及其内容。


附录:Javascript

对于 Javascript,您需要使用稍微复杂一点的方法,Javascript 没有lookbehind assertions,我们在允许的单词前面加上假冒它们。(?:^|\\s)

这将起作用:

  var t = 'some parent +kid -control "human huhu right" world';
  var r = /(?:"[^"]+")?(?:^|\s)(\b\w+)/g;
  var a = [];
  while(m = r.exec(t)) a.push(m[1]);

$1我们在这里使用相同的技术 -为我们需要的单词生成捕获的子匹配。

数组a, ( document.getElementById("myhtml").innerHTML = a;) 的内容将包含:

some,parent,world
于 2012-07-30T13:05:11.227 回答