1

我目前正在使用preg_match_all()查找以特定前缀开头的所有单词。例如,如果前缀是catcatsup则将被视为匹配,而housecat不会。

一旦找到这些实例和它们的偏移量,我就在它们之间循环,基本上用锚标记封装它们。

(问题在代码下方继续)


//Escape all non-standard characters
$preffix = sanitizePreffix($part['modlnoPreffix']);

//All Words Starting with preffix string
$pattern = "/".$preffix.'/'; 

//Find Matches
preg_match_all($pattern , $item['body'], $matches,PREG_OFFSET_CAPTURE);
$matches = array_reverse($matches[0]);

if (count($matches)>0){
    foreach ($matches as $match){
        $text = $match[0];
        $offset = (int)$match[1];
        $endOffset = $offset + strlen($text);
        $url = "/specsheet_getPreffixParts.php?m=".urlencode($text);

        //Insert ending </a> Tag                    
        $item['body'] = str_insert('</a>', $item['body'], $endOffset);

        //Insert Starting <a ...> Tag
        $item['body'] = str_insert("<a rel='".$url."' href='javascript:void(0);'>", $item['body'], $offset);
    }
}

一个问题是我需要检查每个结果索引以确保

  1. 结果还没有<a href='...'>catsup</a>
  2. 结果不在起始<a>标签本身之内<a href='/part/catsup'> ... </a>

我确信我可以轻松地创建一个函数,该函数一次后退一个字符搜索<a,然后一次前进一个字符查找</a>,但这对我来说似乎有点傻。

我的问题是:有没有更好的方法来做到这一点?我最初的直觉是让这部分成为preg_match_all- 换句话说......使用的初始搜索模式的一部分。

我怎么会find all words that start with 'cat' but are not located between a '<a' and a '</a>'

4

2 回答 2

1

描述

这将在锚标记之外查找所有带有前缀“cat”的单词

您需要在正则表达式搜索命令上使用不区分大小写的选项。

(?<=^|<[\/]a>)[^<]*\b(cat\w*|[^<]*?\s\bcat\w*)\b

在此处输入图像描述

正则表达式的 PHP 示例

 <?php
$sourcestring="CatSoup<a href='...'>catsup</a>catfish tag itself like <a href='/part/catsup'> ... </a>";
preg_match_all('/(?<=^|<[\/]a>)[^<]*\b(cat\w*|[^<]*?\s\bcat\w*)\b/i',$sourcestring,$matches);
echo "<pre>".print_r($matches,true);
?>

$matches Array:
(
    [0] => Array
        (
            [0] => CatSoup
            [1] => catfish
        )

    [1] => Array
        (
            [0] => CatSoup
            [1] => catfish
        )

)

要捕获字符串中的位置,您将使用标志 PREG_OFFSET_CAPTURE,但我不确定如何从数组中提取该值。 preg_match_all('/<a\b[^>]*>(cat\w*|[^<]*?\s\bcat\w*)/i',$sourcestring,$matches, PREG_OFFSET_CAPTURE);

免责声明

真正应该首先使用 html 解析引擎提取内部文本,这将避免正则表达式解析 HTML 文本将失败的有问题的边缘情况。但是,我在 OP 的评论中看到您可以控制 HTML,而且它相当基本,因此此免责声明可能并不真正适用。

于 2013-05-22T15:24:55.610 回答
1

我不同意使用解析器的建议不一定适用于这个问题。我会说它确实如此,看起来您正在处理足够的结构复杂性以使正则表达式方法不可行。

但是,假设您实际上正在处理一个足够基本的 HTML 语法子集以由正则表达式解析,那么我注意到在给出的示例中,您可以在<\a>某处寻找匹配的字符串,并在匹配出现时拒绝匹配,这可以通过足够简单的前瞻来完成,例如:

$pattern = "/".$preffix.'(?!.*<\/a>)/';

或者,为了确保前瞻只查看下一个看到的标签,

$pattern = "/".$preffix.'(?![^<]*<\/a>)/';
于 2013-05-22T15:38:32.840 回答