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

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

FOO[BAR]

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

например.

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

Ответ 1

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

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

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

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

Matcher m = MY_PATTERN.matcher("FOO[BAR]");
while (m.find()) {
    String s = m.group(1);
    // s now contains "BAR"
}

Ответ 2

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

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(']'));

Ответ 3

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

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

Ответ 4

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

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

Ни одно из Regexes не будет работать.

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

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

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

Ответ 5

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]

Ответ 6

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

/FOO\[(.+)\]/

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

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

Pattern p = Pattern.compile("FOO\\[(.+)\\]");
Matcher m = p.matcher(inputLine);

Ответ 7

String input = "FOO[BAR]";
String result = input.substring(input.indexOf("[")+1,input.lastIndexOf("]"));

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

Foo [Bar] = > Bar

Foo [Bar [test]] = > Bar [test]

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

Ответ 8

предполагая, что никакая другая закрывающая квадратная скобка не допускается внутри, /FOO \[([^ \]] *) \]/

Ответ 9

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

FOO\\[([^\\]]+)\\]

Ответ 10

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

Ответ 11

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

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/

Ответ 12

"FOO[DOG]".replaceAll("^.*?\\[|\\].*", "");

Это вернет строку взять только строку в квадратных скобках.

Это удалит всю строку снаружи из квадратных скобок.

Вы можете проверить этот пример кода Java онлайн: http://tpcg.io/wZoFu0

Вы можете проверить это регулярное выражение здесь:https://regex101.com/r/oUAzsS/1