Использование Java для поиска подстроки большей строки с помощью регулярного выражения
Если у меня есть строка, как это:
FOO[BAR]
мне нужен общий способ получить строку" BAR " из строки, чтобы независимо от того, какая строка находится между квадратными скобками, она могла бы получить строку.
например
FOO[DOG] = DOG
FOO[CAT] = CAT
11 ответов:
вы должны быть в состоянии использовать не жадные кванторы, в частности *?. Вы, вероятно, захотите следующее:
Pattern MY_PATTERN = Pattern.compile("\[(.*?)\]");это даст вам шаблон, который будет соответствовать вашим строку и поместить текст в квадратных скобках в первой группе. Взгляните на Pattern API Documentation для получения дополнительной информации.
чтобы извлечь строку, вы можете использовать что-то вроде следующего:
Matcher m = MY_PATTERN.matcher("FOO[BAR]"); while (m.find()) { String s = m.group(1); // s now contains "BAR" }
нерегулярный способ:
String input = "FOO[BAR]", extracted; extracted = input.substring(input.indexOf("["),input.indexOf("]"));кроме того, для немного лучшей производительности / использования памяти (Спасибо Hosam):
String input = "FOO[BAR]", extracted; extracted = input.substring(input.indexOf('['),input.lastIndexOf(']'));
это рабочий пример :
RegexpExample.java
package org.regexp.replace; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexpExample { public static void main(String[] args) { String string = "var1[value1], var2[value2], var3[value3]"; Pattern pattern = Pattern.compile("(\[)(.*?)(\])"); Matcher matcher = pattern.matcher(string); List<String> listMatches = new ArrayList<String>(); while(matcher.find()) { listMatches.add(matcher.group(2)); } for(String s : listMatches) { System.out.println(s); } } }отображается :
value1 value2 value3
Если вам просто нужно получить то, что находится между
[], вы можете использовать\[([^\]]*)\]такой:Pattern regex = Pattern.compile("\[([^\]]*)\]"); Matcher m = regex.matcher(str); if (m.find()) { result = m.group(); }Если вам нужно, чтобы он был в форме
identifier + [ + content + ]тогда вы можете ограничить извлечение содержимого только тогда, когда идентификатор является буквенно-цифровым:[a-zA-Z][a-z-A-Z0-9_]*\s*\[([^\]]*)\]это будет проверять такие вещи, как
Foo [Bar]илиmyDevice_123["input"]например.главная проблема
основная проблема заключается в том, когда вы хотите извлечь содержание чего-то вроде этого:
FOO[BAR[CAT[123]]+DOG[FOO]]регулярное выражение не будет работать и вернется
BAR[CAT[123иFOO.
Если мы изменим регулярное выражение на\[(.*)\]тогда мы в порядке, но тогда, если вы пытаетесь извлечь содержимое из более сложных вещей, таких как:FOO[BAR[CAT[123]]+DOG[FOO]] = myOtherFoo[BAR[5]]ни одно из регулярных выражений не будет работать.
наиболее точное регулярное выражение для извлечения правильного содержимого во всех случаях было бы намного сложнее, поскольку оно должно было бы сбалансировать
[]пары и дать вам их содержание.простое решение
если ваши проблемы становятся сложными и содержание
[]произвольный, вы могли бы вместо этого сбалансировать пары[]и извлечь строку, используя простой старый код rathe, чем регулярное выражение:int i; int brackets = 0; string c; result = ""; for (i = input.indexOf("["); i < str.length; i++) { c = str.substring(i, i + 1); if (c == '[') { brackets++; } else if (c == ']') { brackets--; if (brackets <= 0) break; } result = result + c; }это больше псевдо-код, чем реальный код, я не JAVA-кодер, поэтому я не знаю, если синтаксис правильный, но это должно быть достаточно легко улучшить.
Что считать, что этот код должен работа и позволяет извлекать содержимое[], как бы сложно это ни было.
import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public static String get_match(String s, String p) { // returns first match of p in s for first group in regular expression Matcher m = Pattern.compile(p).matcher(s); return m.find() ? m.group(1) : ""; } get_match("FOO[BAR]", "\[(.*?)\]") // returns "BAR" public static List<String> get_matches(String s, String p) { // returns all matches of p in s for first group in regular expression List<String> matches = new ArrayList<String>(); Matcher m = Pattern.compile(p).matcher(s); while(m.find()) { matches.add(m.group(1)); } return matches; } get_matches("FOO[BAR] FOO[CAT]", "\[(.*?)\]")) // returns [BAR, CAT]
Я думаю, что ваше регулярное выражение будет выглядеть так:
/FOO\[(.+)\]/предполагая, что FOO будет постоянным.
Итак, чтобы поместить это в Java:
Pattern p = Pattern.compile("FOO\[(.+)\]"); Matcher m = p.matcher(inputLine);
String input = "FOO[BAR]"; String result = input.substring(input.indexOf("[")+1,input.lastIndexOf("]"));это вернет значение между первым ' ['и последним']'
Foo[Bar] = > Bar
Foo[Bar[test]] = > Bar[test]
Примечание: Вы должны добавить проверку ошибок, если входная строка не является хорошо сформированным.
предполагая, что никакая другая закрывающая квадратная скобка не допускается внутри, /FOO\[([^\]]*)\]/
Я бы определил, что я хочу максимальное количество не -] символов между
[и]. Они должны быть экранированы с обратными косыми чертами (и в Java, они должны быть экранированы снова), и определение non-] является классом символов, таким образом, внутри[и](т. е.[^\]]). Результат:FOO\[([^\]]+)\]
Как это его работа, если вы хотите, чтобы разобрать некоторую строку, которая исходит от mYearInDB.toString() =[2013] это даст 2013
Matcher n = MY_PATTERN.matcher("FOO[BAR]"+mYearInDB.toString()); while (n.find()) { extracredYear = n.group(1); // s now contains "BAR" } System.out.println("Extrated output is : "+extracredYear);
это регулярное выражение работает для меня:
form\[([^']*?)\]пример:
form[company_details][0][name] form[company_details][0][common_names][1][title]выход:
Match 1 1. company_details Match 2 1. company_detailsпроверено на http://rubular.com/
Comments