web-dev-qa-db-fra.com

Utilisation de Java pour trouver la sous-chaîne d'une chaîne plus grande à l'aide d'une expression régulière

Si j'ai une chaîne comme celle-ci:

FOO[BAR]

J'ai besoin d'un moyen générique pour extraire la chaîne "BAR" de la chaîne afin que, quelle que soit la chaîne située entre les crochets, elle puisse obtenir la chaîne.

par exemple.

FOO[DOG] = DOG
FOO[CAT] = CAT
126
digiarnie

Vous devriez pouvoir utiliser des quantificateurs non gourmands, en particulier *? Vous allez probablement vouloir ce qui suit:

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

Cela vous donnera un motif qui correspondra à votre chaîne et mettra le texte entre les crochets du premier groupe. Consultez le Documentation de l'API de modèle pour plus d'informations.

Pour extraire la chaîne, vous pouvez utiliser quelque chose comme:

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

la manière non-regex:

String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf("["),input.indexOf("]"));

alternativement, pour une performance légèrement meilleure/utilisation de la mémoire (merci Hosam):

String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf('['),input.lastIndexOf(']'));
30
zaczap

Ceci est un exemple de travail:

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);
        }
    }
}

Il affiche :

value1
value2
value3
25
Djahid Bekka

Si vous avez simplement besoin d'obtenir tout ce qui se trouve entre _[]_, vous pouvez utiliser \[([^\]]*)\] comme ceci:

_Pattern regex = Pattern.compile("\\[([^\\]]*)\\]");
Matcher m = regex.matcher(str);
if (m.find()) {
    result = m.group();
}
_

Si vous en avez besoin sous la forme identifier + [ + content + ], vous pouvez limiter l'extraction du contenu uniquement lorsque l'identifiant est alphanumérique:

_[a-zA-Z][a-z-A-Z0-9_]*\s*\[([^\]]*)\]
_

Cela validera des choses comme _Foo [Bar]_ ou _myDevice_123["input"]_ par exemple.

Problème principal

Le problème principal est lorsque vous voulez extraire le contenu de quelque chose comme ceci:

_FOO[BAR[CAT[123]]+DOG[FOO]]
_

La regex ne fonctionnera pas et renverra _BAR[CAT[123_ et FOO.
Si nous modifions la regex en \[(.*)\] alors tout va bien, mais si vous essayez d'extraire le contenu d'éléments plus complexes tels que:

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

Aucune des expressions rationnelles ne fonctionnera.

Le regex le plus précis pour extraire le contenu approprié dans tous les cas serait beaucoup plus complexe car il faudrait équilibrer _[]_ paires et vous en fournir le contenu.

ne solution plus simple

Si vos problèmes deviennent complexes et que le contenu de _[]_ est arbitraire, vous pouvez plutôt équilibrer les paires de _[]_ et extraire la chaîne à l'aide de l'ancien code brut plutôt que d'une expression rationnelle:

_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;
}   
_

C'est plus du pseudo-code que du code réel, je ne suis pas un codeur Java, donc je ne sais pas si la syntaxe est correcte, mais il devrait être assez facile de l'améliorer.
Ce qui compte, c’est que ce code fonctionne et vous permette d’extraire le contenu de _[]_, quelle que soit sa complexité.

5
Renaud Bompuis
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
dansalmo

Je pense que votre expression habituelle ressemblerait à ceci:

/FOO\[(.+)\]/

En supposant que FOO sera constant.

Donc, pour mettre cela en Java:

Pattern p = Pattern.compile("FOO\\[(.+)\\]");
Matcher m = p.matcher(inputLine);
2
Kevin Lacquement
String input = "FOO[BAR]";
String result = input.substring(input.indexOf("[")+1,input.lastIndexOf("]"));

Cela retournera la valeur entre le premier '[' et le dernier ']'

Foo [Bar] => Bar

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

Remarque: Vous devez ajouter une vérification d'erreur si la chaîne d'entrée n'est pas bien formée.

1
amit

Cette expression rationnelle fonctionne pour moi:

form\[([^']*?)\]

exemple:

form[company_details][0][name]
form[company_details][0][common_names][1][title]

sortie:

Match 1
1.  company_details
Match 2
1.  company_details

Testé sur http://rubular.com/

0
rusllonrails

en supposant qu’aucun autre crochet de fermeture n’est autorisé à l'intérieur de/FOO\[([^ \]] *) \] /

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

Cela retournera une chaîne ne prenant que la chaîne entre crochets.

Ceci supprime toute la chaîne en dehors des crochets.

Vous pouvez tester cet Java exemple de code en ligne: http://tpcg.io/wZoF

Vous pouvez tester cette expression rationnelle à partir d’ici: https://regex101.com/r/oUAzsS/1

Je définirais que je veux un nombre maximal de non] caractères compris entre _[_ et _]_. Ceux-ci doivent être échappés avec des barres obliques inverses (et en Java, elles doivent être échappées à nouveau), et la définition de non] est une classe de caractères, donc entre _[_ et _]_ (c'est-à-dire _[^\\]]_). Le résultat:

_FOO\\[([^\\]]+)\\]
_
0
Fabian Steeg

Comme cela son travail si vous voulez analyser une chaîne qui vient de mYearInDB.toString () = [2013] il donnera 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
user665270