Проблема в том, что ваш s-режим .*?
может соответствовать угловым скобкам, а также символам новой строки. Если регулярное выражение начинает соответствовать элементу, который не может соответствовать, ничто не мешает ему продолжить попытку сопоставления в следующем элементе. Если вы знаете, что в тексте никогда не будет угловых скобок, вы можете ограничить совпадение одним элементом:
<item name='GenMsgText'><text>([^<>\n]*\n[^<>]*)</text></item>
РЕДАКТИРОВАТЬ: Важно отметить, что регулярные выражения, предлагаемые Максом и Кибби, должны не применяться в s-режиме (/ s, однострочный, DOTALL ...). Это то, что удерживает их от совпадения за концом элемента «item»: чтобы достичь следующего, им нужно будет сопоставить разделители строк между элементами.
Но даже без модификатора / s оба регулярных выражения могут потерпеть неудачу, если в последовательных строках есть два элемента без внутренних перевода строки (т. Е. Только с одним переводом строки между ними). Например, эти две строки будут соответствовать одной:
<item name='GenMsgText'><text>foo</text></item>
<item name='GenMsgText'><text>bar</text></item>
С другой стороны, что если в тексте более двух строк? Другие регулярные выражения соответствуют ровно одному переводу строки, поэтому они потерпят неудачу. В моем регулярном выражении я явно сопоставляю первый перевод строки, чтобы убедиться, что он есть, но если есть еще переводы строки, они будут сопоставлены вторым классом символов: [^<>]*
Именно из-за этого я стараюсь избегать использования .*
или .*?
.