Réponses:
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 modèle qui correspondra à votre chaîne et mettra le texte entre crochets dans le premier groupe. Consultez la documentation de l'API Pattern pour plus d'informations.
Pour extraire la chaîne, vous pouvez utiliser quelque chose comme ce qui suit:
Matcher m = MY_PATTERN.matcher("FOO[BAR]");
while (m.find()) {
String s = m.group(1);
// s now contains "BAR"
}
la manière non-regex:
String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf("["),input.indexOf("]"));
alternativement, pour une meilleure performance / utilisation de la mémoire (merci Hosam):
String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf('['),input.lastIndexOf(']'));
lastIndexOf(']')
place, qui gérerait les crochets imbriqués. De plus, je pense que l'utilisation du indexOf(char)
serait plus rapide que indexOf(String)
.
lastIndexOf
sera certainement plus rapide de trouver la parenthèse de fermeture.
Voici 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
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]
Si vous avez simplement besoin d'obtenir ce qui se trouve entre les deux []
, 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 de la forme, identifier + [ + content + ]
vous pouvez limiter l'extraction du contenu uniquement lorsque l'identifiant est un 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 souhaitez extraire le contenu de quelque chose comme ceci:
FOO[BAR[CAT[123]]+DOG[FOO]]
Le Regex ne fonctionnera pas et reviendra BAR[CAT[123
et FOO
.
Si nous changeons l'expression régulière en \[(.*)\]
alors tout va bien, mais si vous essayez d'extraire le contenu de choses plus complexes comme:
FOO[BAR[CAT[123]]+DOG[FOO]] = myOtherFoo[BAR[5]]
Aucun des Regex 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 les []
paires et vous donner leur contenu.
Une solution plus simple
Si vos problèmes deviennent complexes et que le contenu est []
arbitraire, vous pouvez à la place équilibrer les paires de []
et extraire la chaîne en utilisant un ancien code plutôt qu'un 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;
}
C'est plus du pseudo-code que du vrai code, je ne suis pas un codeur Java donc je ne sais pas si la syntaxe est correcte, mais cela devrait être assez facile à améliorer.
Ce qui compte, c'est que ce code doit fonctionner et vous permettre d'extraire le contenu du []
, aussi complexe soit-il.
Je pense que votre expression régulière ressemblerait à:
/FOO\[(.+)\]/
En supposant que FOO va être constant.
Donc, pour mettre cela en Java:
Pattern p = Pattern.compile("FOO\\[(.+)\\]");
Matcher m = p.matcher(inputLine);
String input = "FOO[BAR]";
String result = input.substring(input.indexOf("[")+1,input.lastIndexOf("]"));
Cela renverra 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.
Je définirais que je veux un nombre maximum de caractères non-] entre [
et ]
. Ceux-ci doivent être échappés avec des barres obliques inverses (et en Java, ils doivent être échappés à nouveau), et la définition de non-] est une classe de caractères, donc à l'intérieur de [
et ]
(ie [^\\]]
). Le résultat:
FOO\\[([^\\]]+)\\]
Comme ça, son travail si vous voulez analyser une chaîne qui provient de mYearInDB.toString () = [2013] cela 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);
Cette expression rationnelle fonctionne pour moi:
form\[([^']*?)\]
exemple:
form[company_details][0][name]
form[company_details][0][common_names][1][title]
production:
Match 1
1. company_details
Match 2
1. company_details
Testé sur http://rubular.com/
"FOO[DOG]".replaceAll("^.*?\\[|\\].*", "");
Cela renverra une chaîne ne prenant que la chaîne entre crochets.
Cela supprime toutes les chaînes en dehors des crochets.
Vous pouvez tester cet exemple de code java en ligne: http://tpcg.io/wZoFu0
Vous pouvez tester cette expression régulière à partir d'ici: https://regex101.com/r/oUAzsS/1