PHP Regex для разбиения строки при первом появлении символа - PullRequest
0 голосов
/ 13 августа 2010

Это может быть неудачный вопрос, но я новичок с регулярными выражениями. У меня есть некоторые текстовые данные в формате:

Название компании: Название компании, место.
Адрес компании: Some, адрес, здесь.
Ссылка: http://www.somelink.com

Теперь я хочу использовать регулярное выражение, чтобы разделить их на массив пар имя: значение. Я пытаюсь использовать регулярное выражение /(.*):(.*)/ с preg_match_all(), и оно хорошо работает с первыми двумя строками, но в третьей строке возвращает «Link: http:» в одной части и «//www.somelink.com» в другом.

Итак, есть ли способ разбить строку только при первом появлении символа ':'?

Ответы [ 2 ]

1 голос
/ 13 августа 2010

Использовать отрицательный класс символов ( см. На rubular.com ):

/^([^:]*):(.*)$/m

[…] - это класс символов . Что-то вроде [aeiou] соответствует одному из строчных гласных. [^…] является отрицательным классом символов. [^aeiou] соответствует одному из всего, кроме строчных гласных.

^ и $ в начале и конце шаблона - это начало и конец строки якоря . Модификаторы m включают многострочный режим .

Проблема с вашим исходным шаблоном заключается в том, что вы (ab) используете ., когда вы могли бы быть намного более конкретным, а поскольку * является жадным, первая группа превзошла все ожидания. Заманчиво попытаться «исправить» это, сделав повторение нежелательным, но MUCH лучше быть более конкретным и сказать, что первая группа соответствует чему-либо, кроме :.

Обратите внимание, что это соответствующий шаблон с захватами. На самом деле это не шаблон split , который соответствует только разделителю. Шаблон разделителя на самом деле просто :.

Похожие вопросы


Фрагмент PHP

Учитывая это:

$text = <<<EOT
Company Name: Name of the company, place.
Company Address: Some, address, here.
Link: http://www.somelink.com
EOT;

preg_match_all('/^([^:]*):(.*)$/m', $text, $matches, PREG_SET_ORDER);

print_r($matches);

Вывод ( как видно на ideone.com ):

Array
(
    [0] => Array
        (
            [0] => Company Name: Name of the company, place.
            [1] => Company Name
            [2] =>  Name of the company, place.
        )

    [1] => Array
        (
            [0] => Company Address: Some, address, here.
            [1] => Company Address
            [2] =>  Some, address, here.
        )

    [2] => Array
        (
            [0] => Link: http://www.somelink.com
            [1] => Link
            [2] =>  http://www.somelink.com
        )

)
0 голосов
/ 13 августа 2010

Вы, вероятно, хотите что-то вроде /(.*?):(.*)/.? после * сделает его "не жадным", поэтому он будет потреблять как можно меньше текста.Я думаю, что это будет работать для вашей ситуации.По умолчанию * является «жадным» и пытается сопоставить столько повторений, сколько может.

Редактировать: См. здесь для получения дополнительной информации о сопоставлении повторений с использованием * и + операторов.

...