2015-12-03 4 views
2

Я пытаюсь сформулировать регулярное выражение в Java для захвата нескольких строк в списке с разделителями пробелов. Вот строка Я пытаюсь захватить с ...Соответствие по подстрокам в разделительном списке с использованием Regex

String output = "regulations { qux def } standards none rules { abc-123 456-defghi wxyz_678 } security { enabled }"; 

И я хочу использовать регулярное выражение для сопоставления каждого слова в пространстве-разделителями списка между скобками сразу после rules. Другими словами, я хотел бы, чтобы регулярное выражение соответствовало abc-123, 456-defghi и wxyz_678. Эти подстроки в этом списке могут содержать любые символы, кроме пробелов, и в списке может быть любое количество подстрок; Я только что использовал приведенные выше 3 специально для иллюстрации на примере. Ниже не работает, так как мне нужно изменить, чтобы быть в состоянии соответствовать несколько раз ...

String regex = "rules\\s\\{\\s([^\\s]*)\\s\\}"; 
final Pattern pattern = Pattern.compile(regex); 
Matcher matcher = pattern.matcher(output); 
while (matcher.find()) { 
    System.out.println(matcher.group(1)); 
} 

Как я могу изменить приведенное выше регулярное выражение для учета несколько возможных совпадений и получить следующий вывод?

abc-123 
456-defghi 
wxyz_678 
+0

Нужен ли вам подход с регулярным выражением? Я думаю, что двухэтапный подход будет более читабельным. –

+0

Честно говоря, я бы очень хотел увидеть как одно, так и двойное регулярное выражение для моего собственного обучения ... – user2150250

ответ

3

Вот 1 шаг: используйте 1 регулярное выражение, чтобы «совместить их все».

regex:

(?:\brules\s+\{|(?!^)\G)\s+([\w-]+) 

Регулярное выражение является соответствие целое слово rules с последующим 1 или более пробельных символов, и если он находит 1 или более пробелов с последующим последовательностей 1 или более алфавитно-цифровых символов или дефисов, то также соответствует сразу после последнего успешного матча. Слово rules - это своего рода граница для нас здесь.

Java code:

String output = "regulations { qux def } standards none rules { abc-123 456-defghi wxyz_678 } security { enabled }"; 
String regex = "(?:\\brules\\s+\\{|(?!^)\\G)\\s+([\\w-]+)"; 
final Pattern pattern = Pattern.compile(regex); 
Matcher matcher = pattern.matcher(output); 
while (matcher.find()) { 
    System.out.println(matcher.group(1)); 
} 

Вот 2-ступенчатый подход: 1) получить подстроку между rules { и }, 2) раскол с пробелами.

String output = "regulations { qux def } standards none rules { abc-123 456-defghi wxyz_678 } security { enabled }"; 
String subst = output.replaceFirst("(?s)^.*\\brules\\s*[{]\\s*([^{}]+)[}].*$", "$1"); 
String[] res = subst.split("\\s+"); 
System.out.println(Arrays.toString(res)); 

См IDEONE demo и regex demo.

Регулярное выражение гораздо проще, он просто соответствует всем вплоть до rules {, а затем захватывает то, что находится внутри {...}, а затем сопоставляет } и остальной части строки. При обратной ссылке $1 мы восстанавливаем значение этой группы в subst переменной. Затем просто разделите.

+0

Я добавлю больше объяснений для первого регулярного выражения, если вы пожелаете, я немного надавил на время прямо сейчас. Главное, что он соответствует и фиксирует * впоследствии * то, что вам нужно с '([\ w -] +)' после 'rules {'. –

+0

Хм, одношаговое решение похоже только на захват первой подстроки, 'abc-123'. https://regex101.com/r/rH6dH3/1 – user2150250

+0

Вы забыли модификатор 'g'. В Java '/ g' is' while (m.find()) {...} '. –

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

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