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



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



FOO[BAR]


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



например



FOO[DOG] = DOG
FOO[CAT] = CAT
783   11  

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

    Ничего не найдено.