Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/246.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 匹配文字字符串_Php_Regex - Fatal编程技术网

Php 匹配文字字符串

Php 匹配文字字符串,php,regex,Php,Regex,我有这个网页,用户可以在其中添加笑脸到他们的评论。我想限制每条评论中笑脸的数量。“系统”工作正常,但我对regex部分有一些问题。 我在配置文件中定义了我的微笑,如下所示: $config['Smilies'] = Array ( // irrelevant stuff 'smilies' => Array ( ':)' => 'smile.gif', ':(' => 'sad.gif', // some more

我有这个网页,用户可以在其中添加笑脸到他们的评论。我想限制每条评论中笑脸的数量。“系统”工作正常,但我对regex部分有一些问题。 我在配置文件中定义了我的微笑,如下所示:

$config['Smilies'] = Array (
    // irrelevant stuff
    'smilies' => Array (
        ':)' => 'smile.gif',
        ':(' => 'sad.gif',
        // some more smilies
        's:10' => 'worship.gif',
        's:11' => 'zip.gif',
        's:12' => 'heart.gif',
        // some more smilies
        's:1' => 'dry.gif',
        's:2' => 'lol.gif',
        's:3' => 'lollol.gif',
        // some more smilies
    )
);
然后,当我验证评论时(看看有多少笑脸),我通过这个数组循环,并将笑脸与评论的内容相匹配。正则表达式的用法如下:

foreach ( $this->config['smilies'] as $smilie => $smilieImage )
{
    $matches = Array ();
    Preg_Match_All ( '/' . Preg_Quote ( $smilie ) . '/i', $Content, $matches );

    $numOfFoundSmilies += Count ( $matches[0] );
}
问题是如果我在注释中输入“s:10”,上面的代码将找到两个匹配项:“s:10”和“s:1”。我对正则表达式的了解非常贫乏,我无法理解这一点。

正则表达式是默认的(至少是PCREs)。通常你可以绕过这一点:

/a+/ # selects the whiole string from "aaaaaaa"

/a+?/ # selects only "a"
对你来说,这没有多大帮助,因为你不能在某个地方打个问号。唯一的可能是重新排序您的搜索数组,并立即替换找到的位置。首先搜索以查找
s:10
,然后搜索以查找
s:1
,并使用而不是匹配项。这样,第二个就再也找不到第一个了

另一种可能性:将搜索数组一分为二。如果您知道,这个循环的结构总是:'加上数字,那么您可以在第二个循环中使用regexp,如下所示

Preg_Match_All ( '/' . Preg_Quote ( $smilie ) . '(?![0-9])/i', $Content, $matches );
使用
(?![0-9])
a查找任何非数字

和第三个:如果您只允许(=转换)特定位置的微笑,您可以使用:

Preg_Match_All ( '/\b' . Preg_Quote ( $smilie ) . '\b/i', $Content, $matches );

\b
是一个“单词边界”,通常不是(字母、数字、下划线)。缺点很明显,并不是所有的笑脸(如“abc;-)xyz”)都会被找到。

您的代码计算每个笑脸代码在帖子中出现的次数,因此“s:10”同时计算为“s:10”和“s:1”

一个解决办法是一次查找所有的微笑代码,这样每一篇文章都只计算一个微笑代码。这可以通过将所有代码组合成一个正则表达式来实现

$codes = array_keys($smilie);
$escCodes = array_map('preg_quote', $codes);
$regex = '/'.implode('|',$escCodes).'/i';

preg_match_all($regex, $Content, $matches);

$found = count($matches);

您可以将正则表达式更改为使用或\s(空格)匹配,使
s:1
变为
\bs:1\b
\ss:1\s
。注意,第二种方法
s:1.
将不匹配,而且两个版本都不匹配
这是我的有趣文本:1

将“s:1”更改为“s:1[^0-9]”—它匹配任何“s:1”,但后面不跟另一个数字。

我想象这段代码比正则表达式快

$replaced = str_replace(array_keys($config['Smilies']), 
                        array_values($config['Smilies']),
                        $message, $count);
但是,这并不能解决
s:1
s:10
的问题,因此我建议对此使用更清晰的分隔符/边界符号,例如
:s10:
而不是
s:10
。那就不再是问题了


此外,我建议无论如何不要使用数字标识符。用户可能会发现记住它们很乏味。为什么不使用易于记忆的标签,例如,
:heart:
:lol:

也许你应该将s:1改为s:01等。我认为这不管用,因为他开始对每个笑脸进行新的正则表达式搜索。就像Fortega说的,这对我不管用。如果我一找到微笑就替换它,这是可能的,但我必须先验证,然后如果验证通过,将文本微笑转换为图像……但是如果替换已经由第一个正则表达式完成,那么第二个正则表达式将找不到s:1+1我使用了您的第二种解决方案(第三种方案不可接受)。我不必将阵列一分为二。工作起来很有魅力!谢谢这同样有效,但我选择了Boldewyn的解决方案,因为它需要更少的代码更改。谢谢你,安威!是的,著名的
表达式+1,我忘记了这个简单的例子。我在一些笑脸上有人类可读的标签,但我无法为30个笑脸找到标签……但是,当它出现在字符串的最后时,它与“s:1”不匹配。正则表达式后面需要另一个字符。在这种情况下,负前瞻会更好:
s:1(?![0-9])