解析短语和关键字的搜索字符串

Posted

技术标签:

【中文标题】解析短语和关键字的搜索字符串【英文标题】:parse search string for phrases and keywords 【发布时间】:2011-12-18 02:37:50 【问题描述】:

我需要解析一个搜索字符串来查找php中的关键字和短语,例如

字符串 1:value of "measured response" detect goal "method valuation" study

将产生:value,of,measured reponse,detect,goal,method valuation,study

如果字符串有,我也需要它来工作:

    没有用引号括起来的短语, 任意数量的短语都用引号括起来,引号外有任意数量的关键字, 仅限引号中的短语, 仅以空格分隔的关键字。

我倾向于使用 preg_match 和模式 '/(\".*\")/' 将短语放入数组中,然后从字符串中删除短语,最后将关键字放入数组中。我就是不能把所有东西都放在一起!

我也在考虑用逗号替换引号外的空格。然后将它们分解成一个数组。如果这是一个更好的选择,我该如何使用preg_replace

有没有更好的方法来解决这个问题?帮助!非常感谢大家

【问题讨论】:

是的,比正则表达式好得多 - 只需使用内置函数 str_getcsv 并将分隔符设置为空格,将附件设置为语音标记:$array = str_getcsv($string, ' ', '"'); 【参考方案1】:
preg_match_all('/(?<!")\b\w+\b|(?<=")\b[^"]+/', $subject, $result, PREG_PATTERN_ORDER);
for ($i = 0; $i < count($result[0]); $i++) 
    # Matched text = $result[0][$i];

这应该会产生您正在寻找的结果。

解释:

# (?<!")\b\w+\b|(?<=")\b[^"]+
# 
# Match either the regular expression below (attempting the next alternative only if this one fails) «(?<!")\b\w+\b»
#    Assert that it is impossible to match the regex below with the match ending at this position (negative lookbehind) «(?<!")»
#       Match the character “"” literally «"»
#    Assert position at a word boundary «\b»
#    Match a single character that is a “word character” (letters, digits, etc.) «\w+»
#       Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
#    Assert position at a word boundary «\b»
# Or match regular expression number 2 below (the entire match attempt fails if this one fails to match) «(?<=")\b[^"]+»
#    Assert that the regex below can be matched, with the match ending at this position (positive lookbehind) «(?<=")»
#       Match the character “"” literally «"»
#    Assert position at a word boundary «\b»
#    Match any character that is NOT a “"” «[^"]+»
#       Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»

【讨论】:

哇。现在将开始工作,一旦我开始工作,defs 会尽快通知您。 跟进:如果我想忽略那些没有用引号括起来的常用词怎么办?喜欢of?假设我有一系列不允许使用的单词,例如array ('at','the','and','of','in'),我如何将其纳入方法中?再次感谢! 哇,我经常使用正则表达式,但这种东西将男人(@FailedDev)与男孩(@davidethell)区分开来。 有一件事,@FailedDev,我如何修改正则表达式模式以在关键字或短语之前保留 hyphen?比如字符串是value of "measured response" -detect goal -"method valuation" study,对应的输出就是value,of,measured reponse,-detect,goal,-method valuation,study? 我尝试在\w 之前插入-?\-? 但它搞砸了.. :/【参考方案2】:

无需使用正则表达式,内置函数str_getcsv 可用于分解带有任何给定分隔符、包围和转义字符的字符串。

真的就这么简单。

// where $string is the string to parse
$array = str_getcsv($string, ' ', '"'); 

【讨论】:

出色的解决方案。 @crishoj 我有我的时刻 ;)【参考方案3】:
$s = 'value of "measured response" detect goal "method valuation" study';
preg_match_all('~(?|"([^"]+)"|(\S+))~', $s, $matches);
print_r($matches[1]);

输出:

Array
(
    [0] => value
    [1] => of
    [2] => measured response
    [3] => detect
    [4] => goal
    [5] => method valuation
    [6] => study
)

这里的技巧是使用 branch-reset 组:(?|...|...)。这就像包含在非捕获组中的交替 - (?:...|...) - 除了在每个分支中捕获组编号以相同的编号开始。 (有关详细信息,请参阅 PCRE docs 并搜索 DUPLICATE SUBPATTERN NUMBERS。)

因此,我们感兴趣的文本总是被捕获的第 1 组。您可以通过$matches[1] 检索所有匹配项的组#1 的内容。 (假设设置了 PREG_PATTERN_ORDER 标志;我没有像 @FailedDev 那样指定它,因为它是默认值。有关详细信息,请参阅 PHP docs。)

【讨论】:

你能在这个正则表达式工作的地方发布一个 perl 测试吗?还是仅在 php 中支持?我希望看到它工作,但我无法让它与我的工具一起工作。 太棒了,艾伦,又学到了新东西。但是,如果我想忽略那些没有用引号括起来的常用词怎么办?像'数组([1] => 数组([1] => of ))'?假设我有一系列不允许使用的单词,例如array ('at','the','and','of','in'),我如何将其纳入方法中?非常感谢! Ana Ban,它对我有用:demo。至于过滤掉常用词,以后就容易多了。 @FailedDev,在 Perl 中,分支重置组仅在 v5.10 及更高版本中受支持。尝试添加use v5.10; pragma。

以上是关于解析短语和关键字的搜索字符串的主要内容,如果未能解决你的问题,请参考以下文章

UITextView 在数据库中搜索关键字

Elasticsearch上的短语和通配符查询

使用熊猫在关键短语后提取字符串的特定部分?

GoogleHacking语法

kibana 使用

使用经典 ASP 检查 SQL Server 表中“标记”短语的字符串