2012-02-20 1 views
1

Я купил RegexBuddy, учитывая его, и если я не согласен на что-то статичное и простое - я просто не могу получить regex!Регулярное выражение для извлечения прогноза погоды и добавления в массив

То, что я пытаюсь сделать, это следующая строка текста; Я хотел бы извлечь информацию о приливах в ассоциативный массив.

High Tide: 2.0m on Mon at 08.54pm and 2.4m on Tue at 09.18am

И в итоге следующий массив:

[0] = 
    'Day' => 'Mon', 
    'Time' => '8.54pm', 
    'Height' => '2.0m', 
    'Tide' => 'High' 

[1] = 
    'Day' => 'Tue', 
    'Time' => '09.18am', 
    'Height' => '2.4m', 
    'Tide' => 'High' 

Концепция Я борюсь с большинства является тот факт, что есть несколько матчей, которые я хотел извлечь (например, 2.0м и 2.4 м). Мне удалось сопоставить на 2.0m и 2.4m, но как определить, какой из них? (Первый прилив против второго прилива).

Любые подсказки?

+1

, где вы получите информацию о том, что вт Прилив "Low"? – Basti

+0

«Скрыть приливы:» всегда присутствует, поэтому вы можете предположить, что информация, следующая сразу, является скрытой волной. Все после «и» является вторым отливом дня. Другими словами, «Скрыть приливы:», «on», «at», «and», «on», «at» всегда присутствуют и статичны. –

+1

На самом деле, я, возможно, пушистый. Эта строка текста для двух отливов в день. Я отредактирую. –

ответ

2
$string = "High Tide: 2.0m on Mon at 08.54pm and 2.4m on Tue at 09.18am"; 

preg_match_all("~((High|Low) Tide:)? (\d.\dm) on (\w{3}) at (.{7})~", $string, $matches, PREG_SET_ORDER); 

var_dump($matches); 

выходы

array 
    0 => 
    array 
     0 => string 'High Tide: 2.0m on Mon at 08.54pm' (length=33) 
     1 => string 'High Tide:' (length=10) 
     2 => string 'High' (length=4) 
     3 => string '2.0m' (length=4) 
     4 => string 'Mon' (length=3) 
     5 => string '08.54pm' (length=7) 
    1 => 
    array 
     0 => string ' 2.4m on Tue at 09.18am' (length=23) 
     1 => string '' (length=0) 
     2 => string '' (length=0) 
     3 => string '2.4m' (length=4) 
     4 => string 'Tue' (length=3) 
     5 => string '09.18am' (length=7) 

я, вероятно, получил вещь о отлива неправильно так что здесь какой-то код без прилива

$string = "High Tide: 2.0m on Mon at 08.54pm and 2.4m on Tue at 09.18am"; 

preg_match_all("~(\d.\dm) on (\w{3}) at (.{7})~", $string, $matches, PREG_SET_ORDER); 

var_dump($matches); 

выходы:

array 
    0 => 
    array 
     0 => string '2.0m on Mon at 08.54pm' (length=22) 
     1 => string '2.0m' (length=4) 
     2 => string 'Mon' (length=3) 
     3 => string '08.54pm' (length=7) 
    1 => 
    array 
     0 => string '2.4m on Tue at 09.18am' (length=22) 
     1 => string '2.4m' (length=4) 
     2 => string 'Tue' (length=3) 
     3 => string '09.18am' (length=7) 
+0

! Благодарю. Ваш ответ - это то, что я принял в конце, так как с небольшими изменениями я смог получить то, что было после, с минимальным регулярным выражением, чтобы понять. –

1

Если слово and всегда разделяет два потока, вы можете разбить строку на две части и обрабатывать каждую половину отдельно. Например:

$str = "High Tide: 2.0m on Mon at 08.54pm and 2.4m on Tue at 09.18am"; 
$data = explode(" and ", $str); 

$result = array(); 
foreach($data as $tide) 
{ 
    $result[] = parseWithRegex($tide); 
} 
1

вы можете использоваться named groups, а затем обратиться к тому, что вы захватили по имени: (?P<name>exp) =>$yourVarName['name']

(не проверял, но это будет идея)

/^[^\d]+(?P<heightOne>[\d\.]+?m)\son\s(?P<dayOne>\w+?)\sat\s(?P<timeOne>.*?(am|pm))\sand\s(?P<heightTwo>[\d\.]+?m)\son\s(?P<dayTwo>\w+?)\sat\s(?P<timeTwo>.*?(am|pm))$/ 
+0

Вы правильно показываете формат именной группы, но в своем регулярном выражении вы делаете '? P: ' – webbiedave

+0

@webbiedave: спасибо, исправлено. – sweaver2112

+0

@ sweaver2112 Спасибо!Я не просто хочу скопировать код и запустить его, так что дайте мне немного взглянуть на это, понять, как он работает, и будет отчитываться (и принимать) соответственно. –

0

Вы можете использовать named capturing groups, чтобы получить ассоциативный массив с результатом и шаблон, соответствующий строке, довольно прямолинейный.

/(?P<tide>high|low)\s+tide:\s+(?P<height1>\d+\.\d+m)\s+on\s+(?P<day1>[a-z]+)\s+at\s+(?P<time1>\d+\.\d+[ap]m)\s+and\s+(?P<height2>\d+\.\d+m)\s+on\s+(?P<day2>[a-z]+)\s+at\s+(?P<time2>\d+\.\d+[ap]m)/i

Пример сценария:

$string = "High Tide: 2.0m on Mon at 08.54pm and 2.4m on Tue at 09.18am"; 

// named groups will also assign matches associative to the matches array, e.g. (?P<tide>high|low) will set $matches["tide"] to 'low' or 'high' 
preg_match(
     '/ 
      (?P<tide>high|low)      # match and capture string "high" or "low" 
      \s+tide:\s+        # match string "tide" surrounded with one or more spaces on each side 
      (?P<height1>\d+\.\d+m)     # match and capture one or more digits followed by a dot and one or more digits followed by an m 
      \s+on\s+        # match string "on" surrounded with one or more spaces on each side 
      (?P<day1>[a-z]+)      # match one or more letters 
      \s+at\s+        # match string "at" surrounded with one or more spaces on each side 
      (?P<time1>\d+\.\d+[ap]m)    # match and capture one or more digits followed by a dot and one or more digits followed by an a or p, and string "m", so am or pm 
      \s+and\s+        # match string "and" surrounded with one or more spaces on each side 
      (?P<height2>\d+\.\d+m)     # match and capture one or more digits followed by a dot and one or more digits followed by an m 
      \s+on\s+        # match string "on" surrounded with one or more spaces on each side 
      (?P<day2>[a-z]+)      # match one or more letters 
      \s+at\s+        # match string "at" surrounded with one or more spaces on each side 
      (?P<time2>\d+\.\d+[ap]m)    # match and capture one or more digits followed by a dot and one or more digits followed by an a or p, and string "m", so am or pm 
     /ix', $string, $matches); 

print_r($matches); 

отпечатывается

Array 
(
    [0] => High Tide: 2.0m on Mon at 08.54pm and 2.4m on Tue at 09.18am 
    [tide] => High 
    [1] => High 
    [height1] => 2.0m 
    [2] => 2.0m 
    [day1] => Mon 
    [3] => Mon 
    [time1] => 08.54pm 
    [4] => 08.54pm 
    [height2] => 2.4m 
    [5] => 2.4m 
    [day2] => Tue 
    [6] => Tue 
    [time2] => 09.18am 
    [7] => 09.18am 
)