2016-08-11 4 views
1

Получил ситуацию, когда регулярное выражение, которое я построил, работает нормально, пока начальная и конечная последовательности находятся на одной строке, а не фрагментированы. В качестве примера, если есть необходимость, чтобы извлечь содержимое из следующего текста между последовательностями ABCDE и VWXYZ он должен вернуть [email protected]#[email protected]#[email protected]##:Как бороться с регулярным выражением, которое имеет какой-либо из его начала и/или конца, разделенных на две строки?

[email protected][email protected][email protected]#@[email protected] 
CDE123456789 
[email protected]#[email protected]#[email protected]##VW 
XYZ00000 

В двух случаях ABCDE отличается. Я надеюсь, что есть способ удовлетворить это на Java.

Благодаря

+0

Похоже, что между 'A',' B', 'C',' D' и 'E' может быть пробел, верно? Попробуйте 'String pat =" (? S) A \\ s * B \\ s * C \\ s * D \\ s * E (. *?) V \\ s * W \\ s * X \\ s * Y \\ s * Z "' –

+0

Проблема не в пробеле, а при переводе новой строки в любую из последовательностей. Таким образом, ABCDE может быть A \ nBCDE или AB \ nCDE и т. Д. –

+0

Вы знаете, что вы всегда можете преобразовать строку в строку с одной строкой? –

ответ

0

Вы можете использовать String pat = "(?s)A\\R*B\\R*C\\R*D\\R*E(.*?)V\\R*W\\R*X\\R*Y\\R*Z" где \\R* соответствует нулю или более переносы строк и (?s) делает точку в .*? матче ноль или более символов (включая символ новой строки) как можно меньше (из-за *? ленивый квантор).

См this IDEONE demo:

String pat = "(?s)A\\R*B\\R*C\\R*D\\R*E(.*?)V\\R*W\\R*X\\R*Y\\R*Z"; 
String s = "[email protected][email protected][email protected]#@[email protected]\nCDE123456789\[email protected]#[email protected]#[email protected]##VW\nXYZ00000"; 
Matcher m = Pattern.compile(pat).matcher(s); 
while(m.find()) 
{ 
    System.out.println(m.group(1)); 
} 

Если она работает плохо, вы можете попробовать другое, развернутое регулярное выражение, но его производительность будет зависеть от того, сколько V символов есть в содержании:

String pat = "A\\R*B\\R*C\\R*D\\R*E([^V]*(?:V(?!\\R*W\\R*X\\R*Y\\R*Z)[^V]*)*)V\\R*W\\R*X\\R*Y\\R*Z"; 

Если у вас могут быть пробелы между буквами, используйте \s* вместо \R*:

String pat = "(?s)A\\s*B\\s*C\\s*D\\s*E(.*?)V\\s*W\\s*X\\s*Y\\s*Z" 
// or 
String pat = "A\\s*B\\s*C\\s*D\\s*E([^V]*(?:V(?!\\s*W\\s*X\\s*Y\\s*Z)[^V]*)*)V\\s*W\\s*X\\s*Y\\s*Z"; 
+0

благодарит Wiktor, что он работает.Если пространство также включено, нужно добавить \\ s после \\ R pls? Если, например, это ABCDE не просто ABCDE. –

+0

См. мое обновление. как я писал в своем первом комментарии, используйте '\ s', который соответствует * any * whitespace. Если у вас есть пробелы Unicode, добавьте' (? U) 'в начале шаблона. –

+0

Замена \ R на \ S не работает по какой-то причине. –