Preg_match, если <code></code> отформатирован правильно - PullRequest
2 голосов
/ 26 февраля 2012
if(preg_match("/(.*(&lt;code&gt;).*(&lt;\/code&gt;).*)*/", $string))

Я пытался уже много часов, но не могу заставить его работать.Я хочу, чтобы, если пользователь отформатировал текст правильно, например:

(any_string*<code>any_string*</code>any_string*)*

Только тогда я отформатировал бы текст с *, означающим пустую строку или много раз.Что не так с моим выражением?

edit: Я хочу соответствовать lalala text <code>dlalala lala code lalalal .Если это lala <code> lalala или lalal lalala <code>alala, то мы не хотим совпадать с ним.

Ответы [ 7 ]

6 голосов
/ 08 марта 2012

Работает с 2 приведенными тестами:

$arr = array('lalala text <code>dlalala lala code</code> lalalal.',
             'lala <code> lalala or lalal </code> <code> lalala <code>alala');
foreach ($arr as $str) {
    echo "$str\n";
    if (preg_match('#^(?<!<code>).*<code>.*?</code>(?!.*<code>)#', $str)) {
        echo "===> Match\n";
    } else {
        echo "===> Not match\n";
    }
}

вывод:

lalala text <code>dlalala lala code</code> lalalal.
===> Match
lala <code> lalala or lalal </code> <code> lalala <code>alala
===> Not match

Некоторые пояснения по регулярному выражению:

#           : regex delimiter
^           : begining of string
  (?<!      : start negative lookbehind
    <code>  : literally <code>
  )         : end of lookbehind
  .*        : any char any number of time
  <code>    : literally <code>
  .*?       : any char any number of time not greedy
  </code>   : literally </code>
  (?!       : start negative lookahead
    .*      : any char any number of time
    <code>  : literally <code>
  )         : end of lookahead
#           : regex delimiter

Вы можете найти некоторые полезные сведения о внешнем виде здесь

4 голосов
/ 04 марта 2012

Вы, вероятно, могли бы использовать greed killer ? в своем выражении кода (дополнительная информация здесь: Соответствие текста между разделителями: жадное или ленивое регулярное выражение? ), поэтому, если у вас есть код, подобный этому:

<code>foo</code> another <code>bar</code> 

Он будет соответствовать просто foo и bar, а не foo другому bar, также вы должны использовать preg_match_all() (с флагом PREG_OFFSET_CAPTURE) и написать свой собственный анализатор. Или, скорее, используйте preg_replace_callback() так:

// Just strtolower example (this would do formatting)
function myCallback( $matches){
    return strlower( $matches[2]);
}

$string = preg_replace_callback("/(&lt;code&gt;).*?(&lt;\/code&gt;)/si", 'myCallback', $string)

Обратите внимание на знак вопроса в .*?. Вам также следует использовать модификаторы s и i, чтобы ваш код работал с такими кодами:

lorem ipsum <code>
foo
</code> bar

Если вам нужна проверка, вы можете использовать это:

$string = preg_replace("/(&lt;code&gt;).*?(&lt;\/code&gt;)/si", '', $string);
if( (strpos( $string, '<code') !== false) || (strpos( $string, '</code') !== false){
    echo 'Invalid code';
}
3 голосов
/ 07 марта 2012
<?php
$string = "aaa<code>asd</code>aaaasd";
if (preg_match("#[a-zA-Z ]+<code>[a-zA-Z ]+<\/code>[a-zA-Z ]+#", $string))
{
echo "It's a match!\n";
} else {
echo "No match, sorry.\n";
}
2 голосов
/ 10 марта 2012
<?php
$sample_text = <<<EOF
blah blah
<code>one</code>
foo<code>two</code>three</code>
<code><code>four</code>bar
</code><code>five</code>foobar
<code>six</code>
blah blah blah
EOF;

preg_match_all('/<code>(?\'code\'((?!<\/?code>).)*)<\/code>/', $sample_text, $codes);

print_r($codes); 
?>

Я считаю, это то, что вы ищете.я сослался на здесь и проверил регулярное выражение здесь .

2 голосов
/ 08 марта 2012

попробуйте эти

$string = "lalala text <code>dlalala lala code</code> lalalal";

if(strlen($string)>0){
    preg_match("/\<code\>(.*)\<\/code\>/",$string, $code);
    echo $code[1];
}else{
    echo "no code found";
}

вывод будет:

dlalala lala код

Удачи:)

2 голосов
/ 06 марта 2012
    $string = "aaa<code>dlalala lala code</code>aaa";
    if (preg_match("#.*<code>.*<\/code>.*#", $string)) {
            echo "OK\n";
    } else {
            echo "NOK\n";
    }
0 голосов
/ 26 февраля 2012

Вам было бы лучше использовать strpos для простых сравнений строк, например, это означает, что вам не нужно беспокоиться о экранировании специальных символов, и это быстрее.

Это будет работать

ИЗМЕНЕНО, ЧТОБЫ ПОЛУЧИТЬ ПОЗИЦИЮ ТЕГОВ.

$string = "This string has 'Anything <code> anything </code> anything' in it in the right order.";
$start = strpos($string, '<code>');
$end = strpos($string, '</code>');
if ($start !== FALSE && $end !== FALSE && $end > $start){
     echo $string;
}else{
    echo 'incorrectly formatted';
}

ЕСЛИ ВЫ ХОТИТЕ ИСПОЛЬЗОВАТЬ PREG_MATCH

if(preg_match("/.*(<code>).*(<\/code>).*/", $string)){
       echo $string
  }

Примечание. Вы не хотите использовать объекты HTML, если не уверены, что строка отформатирована с использованием объектов HTML. Вам не нужен внешний набор скобок.

...