php REGEX, пытающийся извлечь два значения (одно необязательное) из строки - PullRequest
0 голосов
/ 02 марта 2011

У меня есть строка со многими строками, и одна из этих строк - это показание температуры и метод, используемый для измерения температуры, например:

Example line 1
temp: 35.20c / 95.36f - axillary
Example line 2

Очевидно, что температура равна "35.20c / 95.36f"и метод "подмышечный".Часть метода является необязательной.У меня проблемы с написанием шаблона REGEX, который будет извлекать оба, поскольку метод может быть необязательным.

Так что, если я запускаю шаблон в preg_match_all () для следующей строки:

temp: 35.20c / 95.36f - axillary
temp: 35.20c / 95.36f
temp: 35.20c / 95.36f - oral

Я ожидаю получить отпечаток, похожий на этот:

Array
(
    [0] => Array
        (
            [0] => temp: 35.20c / 95.36f - axillary
            [1] => temp: 35.20c / 95.36f
            [2] => temp: 35.20c / 95.36f - oral
        )

    [1] => Array
        (
            [0] => 35.20c / 95.36f
            [1] => 35.20c / 95.36f
            [2] => 35.20c / 95.36f
        )

    [2] => Array
        (
            [0] => axillary
            [1] => 
            [2] => oral
        )

Я пробовал много разных шаблонов, поэтому я просто опубликую свой оригинал (что имеет смысл для меня):

$ptn = "/temp: *(.+)(?: - )?(.+)?/";

Извините, ребята. Думаю, мне нужно добавить еще несколько деталей:

  • Я понятия не имею, в каком формате будет отображаться темп (35.20c / 95.36f, 35c, 95.3f,и т.д.)
  • Мне просто нужно взять все после "temp:" и перед дефисом в качестве моего temp, и все, что после этого будет моим методом.

Ответы [ 6 ]

1 голос
/ 02 марта 2011

Мне кажется, что вы хотите:

/^temp: (\d+\.\d+)c \/ (\d+\.\d+)f(?: - ([^$]+))?$/

Температура по Цельсию будет в 1 долларе, версия по Фаренгейту - в 2 доллара, а метод - в 3 доллара.([^$]+) может быть неправильным в зависимости от того, что вы хотите сделать, так как он будет захватывать все до конца строки (например, пробел, если он есть).Вместо этого вы могли бы использовать (?: - ([^$]+?))?\s*$/ в конце, думаю, это бы исправило это.

Температура всегда в десятичном формате?Могли ли они когда-нибудь просто быть "0c / 32f"?


Редактировать: Только что видел ваше обновление.Похоже, что жадный .+ действительно является частью проблемы, как предложил Роб Агар.Вы можете попробовать это:

/^temp:\s*(\d+(?:\.\d+)?)c\s*\/\s*(\d+(?:\.\d+)?)f(?:\s*-\s*([^$]+?))?\s*$/

Это должно работать, даже если метод состоит из более чем одного слова.Не уверен, что это возможно, я делаю все возможное, чтобы угадать ваши требования.

1 голос
/ 02 марта 2011

Ах, я думаю, что ваша проблема с (. +) Соответствием всему.Шаблоны регулярных выражений являются «жадными» и будут пытаться соответствовать как можно больше.Этот шаблон соответствует остальной части строки, не оставляя ничего для других групп.

1 голос
/ 02 марта 2011

Попробуйте это:

<?php

    $lines = "temp: 35.20c / 95.36f - axillary
temp: 35.20c / 95.36f
temp: 35.20c / 95.36f - oral";

  preg_match_all("/^temp:\s+([^-\n]+)( - )?(.*)/m", $lines, $matches);

  print_r($matches);

?>
0 голосов
/ 02 марта 2011

$ ptn = "/ temp: (. ) (\ s- \ s)? (. ) /";

0 голосов
/ 02 марта 2011

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

/^temp: ((\d+\.\d+c) / (\d+\.\d+f))( - (\w+))?$/

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

0 голосов
/ 02 марта 2011

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

...