PHP и регулярное выражение: ключевое слово встречается один раз - PullRequest
1 голос
/ 16 января 2011

как я могу убедиться, что определенное ключевое слово встречается только один раз во входе с регулярным выражением?

Я думаю, что в приведенном ниже выражении есть некоторые ошибки, поскольку я могу повторить те же ключевые слова,

if (!preg_match('/\b(.php?){1}\b/', $cfg_path))
    {
        $error = true;
        echo '<error elementid="cfg_path" message="PATH - make sure you have a \'.php?\' in the path."/>';
    }

Я просто хочу, чтобы это было правдой,

form.php?category=something or form.php?

, но не это,

form.php?.php?category=something or form.php?.php?

, пожалуйста, дайте мне знать, как это исправить.

спасибо.

Ответы [ 4 ]

2 голосов
/ 16 января 2011

try preg_match_all, который возвращает количество вхождений в строке.

if ( preg_match_all ("~\.php\?~", $cfg_path, $match ) > 1 ){
    $error = true;
    echo '<error elementid="cfg_path" message="PATH - make sure you have a \'.php?\' in the path."/>';
}

Дополнительная информация о preg_match_all здесь PHP: preg_match_all - Manual

Но, если бы я писал этот код, я бы полностью избежал использования регулярных выражений.как

if (  substr_count($cfg_path, ".php?") > 1 ){
    $error = true;
    echo '<error elementid="cfg_path" message="PATH - make sure you have a \'.php?\' in the path."/>';
}

Подробнее о substr_count здесь: PHP: substr_count - Руководство

1 голос
/ 16 января 2011

Вы на правильном пути.Вам необходимо выделить специальные символы в регулярном тексте.?является специальным символом и должен быть экранирован с помощью \ ?, также точка должна экранироваться с косой чертой.

Наконец, вы не должны использовать опцию \ b, это не применимо в вашей ситуации.

Попробуйте:

if (!preg_match('/(\.php\?){1}/', $cfg_path))
{
    $error = true;
    echo '<error elementid="cfg_path" message="PATH - make sure you have a \'.php?\' in the path."/>';
}
0 голосов
/ 16 января 2011

Что такое более одного раза?Вы заявляете, что хотите увидеть его только один раз.Если то, что вы не хотите видеть, является последовательным .php?.php?с возможным больше .php?будет ли возможно больше в строке?

Независимо от того, что вы думаете, когда смотрите на подстроку, есть другие части строки, которые имеют непосредственное влияние на нее.1004 * Это решает проблему:
/^(((?!\.php\?).)*\.php\?){1}((?!\.php\?).)*$/

use strict;
use warnings;

my @samples  = (
 'form.php?category=something',
 'form.php?.php?category=something', 
 'form.php?category=something.php?',
 '.php? form.php?category=something',
 '.php? ok',
 'ok .php?',
);

for (@samples)
{
    if ( /^(((?!\.php\?).)*\.php\?){1}((?!\.php\?).)*$/x ) {
        print "Once:    $_\n\n";
    }
    else {
        print "Failed:  $_\n\n";
    }
}
0 голосов
/ 16 января 2011

Как сказал Дмитрий, вам нужно больше убегать.

* * * * * * В регулярных выражениях {1} не гарантирует, что шаблон встречается только один раз во всем объекте.Это квантификатор только для предыдущей строки.

В противном случае проверьте вручную, как часто оно соответствует:

preg_match_all("/(\.php\??)/", $str, $m);
$matched_once = count($m[1]) == 1;

Если вы хотите проверить всю строку, то вам нужно указать полный шаблон,Используйте ^ или $.Например, в вашем случае:

 preg_match("/\.php(\?[^?]*|)$/", $str)

Где оно либо соответствует .php?... (со всем, кроме знаков вопроса после), либо просто .php в самом конце ($ отмечает конец в регулярных выражениях).

...