2016-02-19 3 views
1

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

Loader[data-prop data-attr="value"] 

Там может быть 1 - п атрибутов. Я хочу извлечь каждый атрибут. (Данные-проп, данные атр = "значение"). Я попробовал это по-разному, например, с \[(?:(\S+)\s)*\], но я не понял это правильно. Выражение должно быть написано в стиле PREG ..

+0

Будет ли каждый элемент Loader иметь такую ​​же строковую структуру? Я имею в виду, что собственность и ценность всегда будут разделены одним пространством? – SebasSBM

+0

Я думаю ['preg_match_all ('~ (?: \ [| (?! ^) \ G) \ s * (\ w + (?: - \ w +) *) (?: ="? ([^ "\] ] *))? ~ ', $ txt, $ matches) '] (https://regex101.com/r/tY6rF6/1) должно быть достаточно. –

ответ

1

Я предлагаю захватывая все ключевые -значные пары с регулярным выражением:

'~(?:([^][]*)\b\[|(?!^)\G)\s*(\w+(?:-\w+)*(?:=(["\'])?[^\]]*?\3)?)~' 

(см regex demo), а затем

См IDEONE demo

$re = '~(?:([^][]*)\b\[|(?!^)\G)\s*(\w+(?:-\w+)*(?:=(["\'])?[^\]]*?\3)?)~'; 
$str = "Loader[data-prop data-attr=\"value\" more-here='data' and-one-more=\"\"]"; 
preg_match_all($re, $str, $matches); 
$arr = array(); 
for ($i = 0; $i < count($matches); $i++) { 
    if ($i != 0) { 
     $arr = array_merge(array_filter($matches[$i]),$arr); 
    } 
} 
print_r(preg_grep('~\A(?![\'"]\z)~', $arr)); 

Выход:

Array 
(
    [3] => data-prop 
    [4] => data-attr="value" 
    [5] => more-here='data' 
    [6] => and-one-more="" 
    [7] => Loader 
) 

Заметки о регулярных выражений (он выглядит слишком сложным):

  • (?:([^][]*)\b\[|(?!^)\G) - граница: мы только начинаем m atching на [, которому предшествует слово (a-zA-Z0-9_) символ (с \b\[) или сразу после успешного матча (с (?!^)\G). Кроме того, ([^][]*) будет захватывать в группу 1 часть перед [.
  • \s* - соответствует ноль или более пробельных символов
  • (\w+(?:-\w+)*) - захватывает в группе 2 "слова" как "word1" или "word1-WORD2" ... "word1-wordn"
  • (?:=(["\'])?[^\]]*?\3)? - необязательная группа (в связи с (?:...)?) соответствие
    • = - знак равенства
    • (["\'])? - Группа 3 (вспомогательная группа для проверки значения разделителя) захвата либо ", ' или ничего
    • [^\]]*? - закрытие ' или " (то же значение, захваченной в 3-й группе) - (значение) ноль или более других, чем ] как можно
    • \3 символов.

Поскольку мы не можем избавиться от захвата ' или ", мы можем preg_grep все элементы, которые мы не заинтересованы в с preg_grep('~\A(?![\'"]\z)~', $arr) где \A(?![\'"]\z) соответствует любой строке, которая не равна ' или ".

+0

Спасибо, но мне действительно нужны группы как строки. Мое намерение состоит в том, чтобы извлечь имя (Loader) в качестве первого совпадения, а остальные - в соответствии с совпадениями. Я пытался добиться этого здесь: https://regex101.com/r/pT9jS2/1, но я не понял его. Моя цель состоит в том, чтобы: mach: 1: Loader/2: data-prop/3: data-attr = "value" – Jon

+0

И сделать это с помощью одного preg_match' захвата * пары ключ-значение? Это невозможно с PCRE. Я обновлю свое решение в соответствии с. к текущим требованиям. –

+0

Извините, что до сих пор использую такое ужасно большое регулярное выражение. Я надеюсь, что он будет работать так, как ожидалось. –

0

, как о чем-то вроде [\s\[]([^\s\]]+(="[^"]+)*)+

дает

MATCH 1: data-prop

MATCH 2: data-attr="value"

Смежные вопросы