2015-03-02 2 views
0

Рассмотрит многострочную строку, состоящую из N lines, как следующее:Regex для разбиения многострочного строки

Line 1 text 
Line 2 text 
Line 3 text 
... 
Line n-1 text 
Line n text 
anchor=value 
Line n+2 text 
Line n+3 text 
Line n+4 text 
... 
Line N text 

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

мне нужно регулярное выражение, которое разбивает выше строку на 3 группы:

  1. линии 1 на линию п (включительно)
  2. анкерной линии (точка раздела)
  3. линии N + 2 на линию N (включительно)

ближайший я получил в растворе

(?s)^(?:(?!anchor\s*=\s*).)+?\r|\nanchor\s*=\s*([^\r\n]+)(?:\r|\n)(.*) 

, но указанное выше регулярное выражение включает весь текст в первой группе соответствия и заполняет оставшиеся 2 группы, как ожидалось.

Дополнительным требованием является то, что регулярное выражение должно быть как можно быстрее, поскольку оно будет применяться к большим объемам данных. Также обратите внимание, что обработка с помощью одного регулярного выражения является единственным вариантом в этом случае использования.

Любые идеи?

ответ

2

Как насчет этого регулярного выражения?

(?s)^(.*?)(anchor\s*\=\s*[^\r\n]+)(.*?)

Или, чтобы соответствовать конец строки,

(?s)^(.*?)(anchor\s*\=\s*[^\r\n]+)(.*?)$?

+0

Первый работает, если нежирный оператор в последней группе становится жадным. Секунды работают так, как есть. Благодаря! – PNS

+0

@PNS, пожалуйста. Я знал, что для шаблона '(. *?)' Может понадобиться какая-то граница, поэтому я добавил второй вариант. –

+0

Да, похоже, все в порядке. Благодарю. – PNS

1

Если вам нужна скорость, огромные строки и регулярное выражение - это не путь. Вы должны иметь всю строку в памяти, чтобы иметь возможность использовать regex для ее токенизации. Использование Reader/InputStreams вместо этого было бы моей рекомендацией.

+0

Конечно, но в этом случае выход получается из библиотеки, которая позволяет настраивать только через регулярное выражение. – PNS

+0

Теперь я еще более смущен. Если вывод поступает из библиотеки, почему вы делаете расщепление? Вы хотите сказать, что строка возвращается библиотекой? – RudolphEst

+0

Он обрабатывается библиотекой, которая позволяет «впрыскивать» регулярные выражения. – PNS

1

Ну, вы могли бы получить первый якорь, а затем разделить на него:

String anchor = str.replaceAll("(?ms).*?(anchor\\s*=.*?)$.*", "$1"); 
String lineParts = str.split("\\Q" + anchor + "\\E"); 

Флаг «м» делает^и старт $ матч/конец строки.

+0

Спасибо, но здесь нужно одно регулярное выражение, которое делает все это, потому что код ничего не позволяет. +1 в любом случае. :-) – PNS

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