2016-04-19 1 views
0

EDIT: Ответ и комментарий ниже заставляют меня думать, что я не объяснил это четко ... Я ищу регулярное выражение, которое соответствует нескольким вхождениям списка. Например, я могу взять ABCBCBCBCBCD, и я хочу получить от него массив [BC, BC, BC, BC, BC]. Я не знаю, сколько предметов будет в списке. Если это ABCD, мне нужен список [bc]. Если это ABCBCD, я хочу [bc, bc]. Я бы мог использовать/A (BC) + D/для соответствия всем вхождениям BC, но это не работает.Preg_match для элементов в списке

оригинальный вопрос ...

У меня есть набор очень больших файлов данных. В файле мне нужен только список элементов. Информация, которую я ищу, имеет формат:

...<RXCUI> <LN ID=531123>Amoxicillin</LN>, <LN ID=441656>Amikacin</LN></ERS>... 

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

preg_match('~<RXCUI>[^<]*(<LN[^>]*>[^<]*</LN>[^<]*)~', $data, $matches); 

Затем $ матчей [1] имеет «Амоксициллин». Я попытался получить все совпадения в списке, используя:

preg_match('~<RXCUI>[^<]*(<LN[^>]*>[^<]*</LN>[^<]*)+~', $data, $matches); 

Это не работает. У меня нет матчей. Каков синтаксис «Несколько совпадений для предыдущей последовательности между (и)»?

отметить, это то, что в $ спичек:

Array (
    [0] => <RXCUI> <LN ID=531123>Amoxicillin</LN>, <LN ID=441656>Amikacin</LN> 
    [1] => <LN ID=531123>Amoxicillin</LN> 
) 

Итак, посмотрел на обоих элементов в списке, но только вернулся первый. Я хочу:

Array (
    [0] => <RXCUI> <LN ID=531123>Amoxicillin</LN>, <LN ID=441656>Amikacin</LN> 
    [1] => <LN ID=531123>Amoxicillin</LN> 
    [2] => <LN ID=441655>Akikacin</LN> 
) 
+0

это не https://regex101.com/r/dZ0vZ3/1 ok? – rock321987

+0

@ rock321987 Это не сработает. Это соответствует всем записям LN. Мне нужны только записи LN, следующие за тегом RXCUI. – kainaw

+0

Все содержимое тега 'LN' внутри' RXCUI' или только первое? – rock321987

ответ

0

Это вы что искали?

preg_match_all("/(\<RXCUI\>.*\<\/LN\>)/", $input_lines, $output_array); 

http://www.phpliveregex.com/p/fpc

+0

Это будет выплевывать весь список как один элемент массива. Верный? То, что я пытаюсь сделать, - это получить каждый элемент в списке как отдельный элемент массива. – kainaw

+0

Правда .. Но разве вы не можете просто взорвать результат на "," и у вас будут две части (или больше)? С шаблоном: '\ (\ . * <\/LN\>)' вы получаете только части LN в массиве, если используете preg_match_all – Andreas

+0

. Предполагается, что в значениях нет запятой. Итак, я должен разработать способ определения только запятых, которые я хочу взорвать. Это то, что я должен сделать, так как я не могу получить регулярное выражение, которое возвращает переменное количество совпадений. – kainaw

0

После долгих исследований, оказалось, что это не может быть сделано с одной функцией preg_match. Это требует двух проходов. Первый будет тянуть весь матч от начала до конца списка. Второй разбьет список в желаемые совпадения.

Первый проход (предположим, $ s = ... <RXCUI> < LN ID = 531123 > амоксициллин </LN >, < LN ID = 441656 > Амикацин </LN> </ERS > ...)

preg_match('~<RXCUI>[^<]*(<LN[^>]*>[^<]*</LN>[^<]*)+</ERS>~', $s, $match1); 

Теперь $ match1 [0] = <RXCUI> < LN ID = 531123 > амоксициллин </LN >, < LN ID = 441656 > Амикацин </LN> </ERS > я могу использовать preg_match_all, чтобы получить именно то, что я хочу между RXCUI и ERS элементов

preg_match_all('~<LN[^>]*>[^<]*</LN>~', $match1[0], $match2); 

Теперь, $ match2 [0] будет содержать массив:

[0] => <LN ID=531123>Amoxicillin</LN> 
[1] => <LN ID=441656>Amikacin</LN> 

Не имеет значения, сколько линий LN есть, второй preg_match_all вернет их все.

Это может быть упрощено, если вы можете убедиться, что в исходном документе нет элементов LN в другом месте. Я знаю, что это элементы LN, которые не входят в раздел RXCUI. Поэтому я не могу просто искать их.

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

  • Нет связанных вопросов^_^