web-dev-qa-db-fra.com

Analyser la chaîne en utilisant Java Regex Pattern?

J'ai la chaîne ci-dessous Java dans le format ci-dessous.

String s = "City: [name:NYK][distance:1100] [name:CLT][distance:2300] [name:KTY][distance:3540] Price:"

En utilisant le package Java.util.regex et les classes de modèles, je dois obtenir la chaîne de sortie au format suivant:

Output: [NYK:1100][CLT:2300][KTY:3540]

Pouvez-vous suggérer un modèle RegEx qui peut m'aider à obtenir le format de sortie ci-dessus?

6
Bharath Reddy

Vous pouvez utiliser cette expression régulière \[name:([A-Z]+)\]\[distance:(\d+)\] avec un modèle comme celui-ci:

String regex = "\\[name:([A-Z]+)\\]\\[distance:(\\d+)\\]";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);

StringBuilder result = new StringBuilder();
while (matcher.find()) {                                                
    result.append("[");
    result.append(matcher.group(1));
    result.append(":");
    result.append(matcher.group(2));
    result.append("]");
}

System.out.println(result.toString());

Sortie

[NYK:1100][CLT:2300][KTY:3540]
  • démo regex
  • \[name:([A-Z]+)\]\[distance:(\d+)\] signifie obtenir deux groupes l'un des lettres supérieures après \[name:([A-Z]+)\] le second obtenir le nombre après \[distance:(\d+)\]

Une autre solution de @ tradeJmark vous pouvez utiliser cette expression régulière:

String regex = "\\[name:(?<name>[A-Z]+)\\]\\[distance:(?<distance>\\d+)\\]";

Ainsi, vous pouvez facilement obtenir les résultats de chaque groupe par le nom du groupe au lieu de l'index comme ceci:

while (matcher.find()) {                                                
    result.append("[");
    result.append(matcher.group("name"));
    //----------------------------^^
    result.append(":");
    result.append(matcher.group("distance"));
    //------------------------------^^
    result.append("]");
}
10
YCF_L

Si le format de la chaîne est fixe et que vous n'avez toujours que 3 [...] groupes à l'intérieur pour traiter , vous pouvez définir un bloc qui correspond à [name:...] et capture les 2 parties dans des groupes séparés et utilise un code assez simple avec .replaceAll:

String s = "City: [name:NYK][distance:1100] [name:CLT][distance:2300] [name:KTY][distance:3540] Price:";
String matchingBlock = "\\s*\\[name:([A-Z]+)]\\[distance:(\\d+)]";
String res = s.replaceAll(String.format(".*%1$s%1$s%1$s.*", matchingBlock), 
    "[$1:$2][$3:$4][$5:$6]");
System.out.println(res); // [NYK:1100][CLT:2300][KTY:3540]

Voir le démo Java et un démo regex .

Le modèle de bloc correspond:

  • \\s* - 0+ espaces blancs
  • \\[name: - un littéral [name: sous-chaîne
  • ([A-Z]+) - Groupe n capturant 1 ou plusieurs majuscules ASCII caractères (\\w+ peut également être utilisé)
  • ]\\[distance: - un littéral ][distance: sous-chaîne
  • (\\d+) - Groupe m capturant 1 ou plusieurs chiffres
  • ] - une ] symbole.

Dans le .*%1$s%1$s%1$s.* pattern, les groupes auront 1 à 6 identifiants (désignés par $1 - $6 références arrière du modèle de remplacement) et le début et la fin .* supprimera le début et la fin de la chaîne (ajoutez (?s) au début du modèle si la chaîne peut contenir des sauts de ligne).

3
Wiktor Stribiżew