Использование Java для поиска подстроки большей строки с использованием регулярного выражения - PullRequest
123 голосов
/ 02 марта 2009

Если у меня есть такая строка:

FOO[BAR]

Мне нужен общий способ получить строку «BAR» из строки, чтобы независимо от того, какая строка заключена в квадратные скобки, она могла бы получить строку.

, например

FOO[DOG] = DOG
FOO[CAT] = CAT

Ответы [ 11 ]

228 голосов
/ 02 марта 2009

Вы должны иметь возможность использовать не жадные квантификаторы, в частности * ?. Вы, вероятно, захотите следующее:

Pattern MY_PATTERN = Pattern.compile("\\[(.*?)\\]");

Это даст вам шаблон, который будет соответствовать вашей строке и поместит текст в квадратные скобки в первой группе. Посмотрите документацию Pattern API для получения дополнительной информации.

Чтобы извлечь строку, вы можете использовать что-то вроде следующего:

Matcher m = MY_PATTERN.matcher("FOO[BAR]");
while (m.find()) {
    String s = m.group(1);
    // s now contains "BAR"
}
30 голосов
/ 02 марта 2009

путь без регулярных выражений:

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(']'));
24 голосов
/ 15 декабря 2011

Это рабочий пример:

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
5 голосов
/ 28 октября 2013
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]
5 голосов
/ 02 марта 2009

Если вам просто нужно получить что-нибудь между [], вы можете использовать \[([^\]]*)\], например:

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]]

Regex не будет работать и вернет BAR[CAT[123 и FOO.
Если мы изменим Regex на \[(.*)\], тогда мы в порядке, но потом, если вы пытаетесь извлечь контент из более сложных вещей, таких как:

FOO[BAR[CAT[123]]+DOG[FOO]] = myOtherFoo[BAR[5]]

Ни одно из регулярных выражений не будет работать.

Самый точный Regex для извлечения правильного контента во всех случаях будет намного сложнее, так как потребуется сбалансировать [] пар и дать вам их контент.

Более простое решение

Если ваши проблемы усложняются, а содержимое [] произвольно, вы можете вместо этого сбалансировать пары [] и извлечь строку, используя обычный старый код, чем регулярное выражение:

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-кодер, поэтому не знаю, правильный ли синтаксис, но его должно быть достаточно легко улучшить.
Считается, что этот код должен работать и позволяет извлекать содержимое [], каким бы сложным оно ни было.

2 голосов
/ 02 марта 2009

Я думаю, что ваше регулярное выражение будет выглядеть так:

/FOO\[(.+)\]/

Предполагая, что FOO будет постоянным.

Итак, чтобы поместить это в Java:

Pattern p = Pattern.compile("FOO\\[(.+)\\]");
Matcher m = p.matcher(inputLine);
1 голос
/ 02 марта 2009
String input = "FOO[BAR]";
String result = input.substring(input.indexOf("[")+1,input.lastIndexOf("]"));

Это вернет значение между первым '[' и последним ']'

Foo [Bar] => Bar

Foo [Bar [тест]] => Бар [тест]

Примечание. Следует добавить проверку ошибок, если входная строка сформирована неправильно.

0 голосов
/ 03 апреля 2015

Это регулярное выражение работает для меня:

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/

0 голосов
/ 18 апреля 2012

Как это работает, если вы хотите проанализировать некоторую строку, которая идет от 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);
0 голосов
/ 02 марта 2009

Я бы определил, что я хочу максимальное количество не] символов от [ до ]. Они должны быть экранированы с помощью обратной косой черты (а в Java их нужно экранировать снова), и определение non-] является классом символов, то есть внутри [ и ] (т.е. [^\\]]). Результат:

FOO\\[([^\\]]+)\\]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...