соответствовать формату и возвращать токены из строки

Я пытаюсь разобрать большой текст с помощью регулярных выражений в PHP. Я знаю формат строк, показанный ниже в формате sprintf, для простоты объяснения.

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

Я пробовал форматы регулярных выражений, такие как '/(?<=new message from )(.*)(?=[)(.*)(?=:)(.*)(?=:)(.*)(?=:)(.*)(?=])/'Но, кроме сопоставления, я не смог извлечь правильные данные из строк.

$input = [
'new message from Bob [22:105:3905:534]',
'user Dylan posted a question in section General',
'new message from Mary(gold) [19504:8728:18524:78941]'
];

$formats = [
'new message from %s [%d:%d:%d:%d]', // this would actually be something like '/(?<=new message from )(.*)(?=[)(.*)(?=:)(.*)(?=:)(.*)(?=:)(.*)(?=])/'
'user %s posted a question in section %s',
'new message from %s(%s) [%d:%d:%d:%d]',
];

foreach ($input as $line) {
foreach ($formats as $key => $format) {
$data = [];
if (preg_match($format, $line, $data)) {
echo 'format: ' . $key . ', data: ' . var_export($data, true) . "\n";
continue;
}
}
}

// should yield:
// format: 0, data: array ( 0 => 'Bob', 1 => 22, 2 => 105, 3 => 3905, 4 => 534, )
// format: 1, data: array ( 0 => 'Dylan', 1 => 'General', )
// format: 2, data: array ( 0 => 'Mary', 1 => 'gold', 2 => 19504, 3 => 8728, 4 => 18524, 5 => 78941, )

Я нуждаюсь:

  1. эффективный формат регулярного выражения для сопоставления строки с использованием нескольких подстановочных знаков
  2. способ извлечения подстановочных знаков, когда формат регулярного выражения совпадает со строкой (возможно, preg_match — не лучшая PHP-функция регулярного выражения для использования в этом случае)

Я могу сделать это с помощью строковых функций (strpos и substr), но код выглядит ужасно ..

Спасибо!

0

Решение

Просто небольшая корректировка по шаблонам. Пожалуйста, смотрите код ниже.

<?php

$input = [
'new message from Bob [22:105:3905:534]',
'user Dylan posted a question in section General with space',
'new message from Mary(gold) [19504:8728:18524:78941]'
];

$formats = [
'/new message from (\w+) \[(\d+):(\d+):(\d+):(\d+)\]/', // this would actually be something like '/(?<=new message from )(.*)(?=[)(.*)(?=:)(.*)(?=:)(.*)(?=:)(.*)(?=])/'
'/user (\w+) posted a question in section ([\w ]+)/',
'/new message from (\w+)\((\w+)\) \[(\d+):(\d+):(\d+):(\d+)\]/',
];

foreach ($input as $line) {
foreach ($formats as $key => $format) {
$data = [];
if (preg_match($format, $line, $data)) {
array_shift($data);
echo 'format: ' . $key . ', data: ' . var_export($data, true) . "\n";
continue;
}
}
}

// should yield:
// format: 0, data: array ( 0 => 'Bob', 1 => 22, 2 => 105, 3 => 3905, 4 => 534, )
// format: 1, data: array ( 0 => 'Dylan', 1 => 'General', )
// format: 2, data: array ( 0 => 'Mary', 1 => 'gold', 2 => 19504, 3 => 8728, 4 => 18524, 5 => 78941, )

https://3v4l.org/NBgaT

РЕДАКТИРОВАТЬ: я добавил array_shift() избавиться от текста, соответствующего полному шаблону.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector