有没有更直接的方法来搜索字符串而忽略空格?

时间:2014-08-25 17:33:30

标签: php regex

我正在开发一个函数,用于搜索字符串中搜索给定单词列表之一。被搜索的字符串由OCR软件生成,偶尔会在字母之间添加额外的空格(取决于字体),我需要忽略它。

我目前的功能如下:

function searchSomeText($searchTerms, $stringToBeSearched)
{
    $matches = array();
    for($i=0; $i < count($searchTerms); ++ $i)
    {
        $searchTerms[$i] = substr(chunk_split($searchTerms[$i],1,"\s*"), 0, -3);
    }
    $searchTermsString = implode("|", $searchTerms);

    if (preg_match("/\b($searchTermsString)\b/", $stringToBeSearched, $matches))
    {
        return $matches;
    }
    else { return false; }
}
  1. 有没有办法忽略空格除了在搜索词中的每个字符之间添加'\s*'
  2. 如果没有,是否有一种更有效的方法可以在搜索字词中的每个字符后添加'\s*',但除了使用chunk_split()每<<}后添加它/ em>字符,然后从最后砍掉它?
  3. 修改

    我不想仅仅从$stringToBeSearched剥离空格,因为在大多数情况下,间距是正确的,我不希望匹配搜索词包含在另一个词内(因此'\b' s)

1 个答案:

答案 0 :(得分:0)

根据我对您的任务的理解,以下是我推荐的策略:

  1. 不要改变 haystack 字符串。通常,要搜索的字符串比搜索中使用的针长得多。应尽可能避免这种潜在的繁重工作。
  2. 您的搜索词似乎是动态的(并且可能来自用户输入),因此必须对字符进行转义以防止正则表达式模式损坏。在此过程中使用 preg_quote()
  3. 在转义搜索词中的所有非空白字符之间插入 \s*(忽略转义斜杠)。
  4. 然后将搜索词中的一个或多个空格的所有序列转换为 \s+
  5. 既然术语已准备好,请使用管道将它们粘在一起。将管道表达式包裹在括号中,然后将该捕获组包裹在字边界标记 (\b) 中。
  6. 虽然您的问题中没有提到,但我建议使用不区分大小写的匹配。如果可能涉及多字节/Unicode 字符,请添加 u 模式修饰符。

推荐代码:(Demo)

function searchSomeText(array $searchTerms, string $stringToBeSearched): bool
{
    foreach ($searchTerms as &$searchTerm) {
        $searchTerm = preg_replace(
            ['/\\\\?\S\K(?=\S)/', '/\s+/'],
            ['\\s*', '\\s+'],
            preg_quote($searchTerm, '/')
        );
    }
    $pattern = '/\b(' . implode("|", $searchTerms) . ')\b/i';
    echo $pattern . "\n";
    return (bool)preg_match($pattern, $stringToBeSearched);
}

var_export(
    searchSomeText(
        ['at', 'cat ', 'the'],
        'The catheter in the hat'
    )
);

输出:(动态正则表达式和返回值)

/\b(a\s*t|c\s*a\s*t\s+|t\s*h\s*e)\b/i
true