如何在php和javascript中使用regex检测空格分隔词(在全文搜索查询中)

how detect space separate words (in a full-text search query) with regex in php and javascript

本文关键字:文搜索 查询 搜索 分隔 检测 php javascript regex 空格      更新时间:2024-04-22

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

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

如果给定以下字符串:

 $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

使用的技术:

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


附录: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中为我们需要的单词生成捕获的子匹配。

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

some,parent,world

尝试:

$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()制作的函数。