2010-11-10 7 views
1

J'ai une chaîne comme:Comment analyser cette chaîne avec regex?

"GOOG",625.00,"-1.95 - -0.31%" 

J'utilise ce modèle, et il ne correspond pas à. J'essaie d'obtenir GOOG. Qu'est-ce que je fais mal?

Pattern pattern = Pattern.compile("^\"([^\"]+)"); 
Matcher matcher = pattern.matcher(line); 

if (matcher.matches()) { 
    Log.i(TAG, matcher.group(0)); 
} else { 
    Log.i(TAG, "no match"); 
} 
+0

Etes-vous bloqué avec regex? –

+0

Le motif me va bien - pouvez-vous vérifier en écrivant les premiers caractères que "line" ne commence pas avec une nouvelle ligne ou quelque chose de fou comme ça? – cdhowie

+0

Utiliser regex pour * analyser * quelque chose est inefficace. Plutôt l'utiliser pour * faire correspondre * quelque chose et utiliser un analyseur complet pour analyser quelque chose. Pour CSV, il existe [parseurs CSV] (http://google.com/search?q = java + csv + parser) (comme les analyseurs HTML existent pour HTML ...). – BalusC

Répondre

0

méthode Java matches() attend la regex pour correspondre à la chaîne entière, comme si elle était ancrée à la fois se termine par ^ et $ (ou \A et \z). Chaque fois que vous utilisez matches() avec une expression régulière qui correspond à une partie seulement de la chaîne, vous devez « pad » l'expression rationnelle .*, comme ceci:

Pattern pattern = Pattern.compile("\"([^\"]+).*"); 
Matcher matcher = pattern.matcher(line); 

if (matcher.matches()) { 
    Log.i(TAG, matcher.group(1)); // not group(0)! 
} else { 
    Log.i(TAG, "no match"); 
} 

Le ^ au début de la regex ne faisait pas de mal , Je l'ai juste enlevé pour montrer que ce n'était pas nécessaire. Notez que j'ai également changé votre group(0) en group(1) - c'était une autre erreur dans votre code. group(0) correspond à l'ensemble de la correspondance, tandis que group(1) correspond uniquement à la partie qui a été trouvée dans le premier jeu de parenthèses de capture.

Vous avez également la possibilité d'utiliser find(), comme ceci:

Pattern pattern = Pattern.compile("\"([^\"]+)"); 
Matcher matcher = pattern.matcher(line); 

if (matcher.find()) { 
    Log.i(TAG, matcher.group(1)); 
} else { 
    Log.i(TAG, "no match"); 
} 

Cela correspond à la première instance d'un guillemet suivi d'un ou plusieurs caractères autres que des guillemets (qui sont capturés dans le groupe n ° 1). Cela va correspondre n'importe où; si vous voulez qu'il correspond seulement au début de la chaîne, vous devez utiliser l'ancre ^ comme vous l'aviez dans votre regex d'origine: "^\"([^\"]+)"

(Il y a aussi une méthode lookingAt(), qui ancre automatiquement le match à la début de la chaîne mais pas la fin, mais personne ne l'utilise jamais.)

+0

Merci, ceci a permis à mon regex de fonctionner. – Joren

3

Le problème est que vous n'êtes pas en cours d'exécution matcher.find() si l'expression est jamais vraiment évalué. Ce que vous avez fonctionnera bien si vous changez juste à:

if (matcher.find()) { 

Bien que cela semble que ce serait plus facile si vous venez d'utiliser la méthode String.split (ou mieux encore, utilisez une bibliothèque pour l'analyse des fichiers CSV):

String temp = "\"GOOG\",625.00,\"-1.95 - -0.31%\""; 
String[] parts = temp.split(","); 
String symbol = temp[0].replaceAll("\"", ""); 
+3

"(ou mieux encore, ** [utiliser] une bibliothèque pour analyser les fichiers CSV **)" –

+0

@pst, merci ... édité –

+1

En supposant que "GOOG" n'aura jamais de virgule dedans mais je pense que c'est peu probable car il gênerait beaucoup de commerçants boursiers :-) – paxdiablo

0

vous devez d'abord appeler matcher.find()

String temp = "\"GOOG\",625.00,\"-1.95 - -0.31%\""; 
Pattern pattern = Pattern.compile("\"[a-zA-Z]*\""); 
Matcher matcher = pattern.matcher(temp); 

if(matcher.find()){ 
    Log.i(TAG, matcher.group(0).split("\"")[1]); 
} else { 
    Log.i(TAG, "no match"); 
} 
0

fami Regex:

^"(?<text>[^"]+?)" 

Je pense que vous manquez deuxième « (l'un après GOOG »)

EDIT:

Pattern pattern = Pattern.compile("^\"([^\"]+)\""); 
+0

'(? ...)' est comment vous spécifiez un * groupe nommé *, mais les expressions rationnelles Java ne les supportent pas encore (ils viennent en Java 7). Et laisser la deuxième citation n'est pas une erreur dans ce cas; le '[^ \"] + 's'arrêtera de correspondre quand il manquera de guillemets (mais j'ajouterais quand même la citation de fermeture, pour éviter toute confusion.) –