Как preg_match_all () обрабатывает строки? - PullRequest
5 голосов
/ 20 октября 2011

Я до сих пор много узнаю о PHP, и изменение строк меня интересует. Ранее я использовал preg_match для таких вещей, как проверка адреса электронной почты или просто поиск запросов.

Я только что пришел из этого поста Что не так в моем регулярном выражении? и мне было любопытно, почему функция preg_match_all создает 2 строки, 1 с некоторыми символами, а затем с другими желаемый вывод.

Из того, что я понимаю о функции, является то, что она перебирает строковый символ за символом, используя RegEx, чтобы оценить, что с ней делать. Мог ли этот RegEx быть структурирован таким образом, чтобы обойти первую запись массива и просто дать желаемый результат?

и вам не нужно переходить к другой теме

$str = 'text^name1^Jony~text^secondname1^Smith~text^email1^example-
        free@wpdevelop.com~';

preg_match_all('/\^([^^]*?)\~/', $str, $newStr);

for($i=0;$i<count($newStr[0]);$i++)
{
    echo $newStr[0][$i].'<br>';
}

echo '<br><br><br>';

for($i=0;$i<count($newStr[1]);$i++)
{
    echo $newStr[1][$i].'<br>';
} 

Это выведет

^ Jony ~
^ Smith ~
^ пример свободной @ wpdevelop.com ~


Джони
Smith
пример свободной @ wpdevelop.com

Мне любопытно, была ли причина для двух записей массива из-за исходного синтаксиса строки или это нормальный ответ обработки функции. Извините, если этого не должно быть здесь, но мне действительно любопытно, как это работает.

спасибо, Броди

Ответы [ 6 ]

2 голосов
/ 20 октября 2011

Может ли это RegEx быть структурировано таким образом, чтобы обойти первую запись массива и просто дать желаемый результат?

Абсолютно.Используйте утверждений .Это регулярное выражение:

preg_match_all('/(?<=\^)[^^]*?(?=~)/', $str, $newStr);

Результат:

Array
(
    [0] => Array
        (
            [0] => Jony
            [1] => Smith
            [2] => example-free@wpdevelop.com
        )

)
2 голосов
/ 20 октября 2011

Это стандартное поведение для preg_match и preg_match_all - первая строка в массиве «совпадающие значения» - это полная строка, которая была захвачена шаблоном регулярных выражений. Последующие значения массива - это «группы захвата», существование которых зависит от размещения / положения пар () в шаблоне регулярных выражений.

В случае вашего регулярного выражения, /\^([^^]*?)\~/, полная совпадающая строка будет

^   Jony    ~
|     |     |
^  ([^^]*?) ~   -> $newstr[0] = ^Jony~
                -> $newstr[1] = Jony (due to the `()` capture group).
1 голос
/ 20 октября 2011

Первый массив в результате preg_match_all возвращает строки, соответствующие всему шаблону, который вы передали функции preg_match_all (), в вашем случае / \ ^ ([^^] *?) \ ~ /.Последующие массивы в результате содержат совпадения для круглых скобок в вашем шаблоне.Возможно, это легче понять на примере:

$string = 'abcdefg';
preg_match_all('/ab(cd)e(fg)/', $string, $matches);

Массив $ match будет иметь значение

array(3) {
  [0]=>
  array(1) {
    [0]=>
    string(7) "abcdefg"
  }
  [1]=>
  array(1) {
    [0]=>
    string(2) "cd"
  }
  [2]=>
  array(1) {
    [0]=>
    string(2) "fg"
  }
}

Первый массив будет содержать совпадение всего шаблона, в данном случае 'АБВГДЕЖ.Второй массив будет содержать совпадение для первого набора скобок, в данном случае «cd».Третий массив будет содержать совпадение для второго набора скобок, в данном случае 'fg'.

1 голос
/ 20 октября 2011

Как указано в руководстве , это ожидаемый результат (для флага PREG_PATTERN_ORDER по умолчанию). Первая запись $newStr содержит все полные совпадения с образцами, следующий результат - все совпадения для первого подшаблона (в скобках) и т. Д.

0 голосов
/ 28 декабря 2012

Всякий раз, когда у вас возникают проблемы с представлением функции preg_match_all, вы должны использовать оценщик, например preg_match_all tester @ regextester.net

Это показывает вам результат в реальном времени, и вы можете настроить такие вещи, какпорядок результатов, мета-инструкции, захват смещения и многое другое.

0 голосов
/ 20 октября 2011

[0] содержит полное совпадение, а [1] только часть (часть, которую вы хотите извлечь) ... Вы можете сделать var_dump($newStr), чтобы увидеть структуру массива, вы поймете это.

$str = 'text^name1^Jony~text^secondname1^Smith~text^email1^example-
        free@wpdevelop.com~';

preg_match_all('/\^([^^]*?)\~/', $str, $newStr);

$newStr = $newStr[1];
foreach($newStr as $key => $value)
{
    echo $value."\n"; 
}

Это приведет к ... (странный результат, без изменения выражения)

Jony
Smith
example-
        free@wpdevelop.com
...