Je veux hotkenize une chaîne comme celle-ci je ne peux pas scinder en fonction de ce p> aucune idée de quoi que je reçois des jetons comme p>
11 Réponses :
Le moyen le plus simple de le faire est de mettre en œuvre une simple machine à états finie. En d'autres termes, traiter la chaîne un caractère à la fois: p>
Une machine d'état bien finie équivaut à une expression régulière afin que vous puissiez rester avec cela, non?
Méfiez-vous que vous devrez peut-être manipuler des devis évasés tels que \ "
Selon le formatage de votre chaîne d'origine, vous devriez pouvoir utiliser une expression régulière comme paramètre sur la méthode Java "Split": Cliquez ici pour un exemple . P>
L'exemple n'utilise pas l'expression régulière dont vous auriez besoin pour cette tâche. P>
Vous pouvez également utiliser Ceci alors thread comme ligne directrice (bien que ce soit en PHP) qui fait quelque chose de très proche de ce dont vous avez besoin. Manipuler que légèrement peut faire l'affaire (bien que d'avoir des devis faire partie de la production ou non peut causer des problèmes). Gardez à l'esprit que Regex est très similaire dans la plupart des langues. P>
EDIT FORT>: aller trop loin dans ce type de tâche peut être en avance sur les capacités de RegEx, vous devrez peut-être créer un analyseur simple. P>
Avez-vous essayé de fractionnement par '=' et créez un jeton de chaque paire de la matrice résultante? P>
Cela a le même problème que la solution .split () mentionnée dans la question.
@rajax Cette solution ne fonctionne pas, mais vous pouvez faire quelque chose comme scinder un espace, puis passer à travers chacune des chaînes fendues: si elle commence par '(en supposant qu'elle soit bien formatée), alors vous venez d'ajouter ces cordes ensemble jusqu'à ce que vous en trouver un qui se termine avec '. String Tokenziers ou une machine à états (ou à l'aide d'une pile si vous souhaitez autoriser plusieurs niveaux de guillemets de nichement en alternant les types de devis ALA Python) peut être plus efficace, mais cela peut aussi fonctionner!
StreamTokenizer peut aider, bien que Il est plus facile de mettre en place pour rompre sur '=', car il va toujours casser au début d'une chaîne citée: sorties p> Si vous laissez les deux lignes qui convertissent des caractères numériques en alpha, vous obtenez d = 777.0 code>, ce qui pourrait vous être utile. P> P>
java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(line, " "); while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); int index = token.indexOf('='); String key = token.substring(0, index); String value = token.substring(index + 1); }
Hypothèses:
Cela fonctionne bien pour moi. p>
entrée: p> sortie: p> code: p>
Cette solution est à la fois générale et compacte (c'est effectivement la version de la regex de la réponse de Cletus): En d'autres termes, trouvez toutes les exécutions de caractères combinant des chaînes citées ou caractères non spatiaux; Les citations imbriquées ne sont pas supportées (il n'y a pas de caractère d'échappement). P> P>
a=b c='123 456' d=777 e='uij yyy'
public static void main(String[] args) { String token; String value=""; HashMap<String, String> attributes = new HashMap<String, String>(); String line = "a=b c='123 456' d=777 e='uij yyy'"; StringTokenizer tokenizer = new StringTokenizer(line," "); while(tokenizer.hasMoreTokens()){ token = tokenizer.nextToken(); value = token.contains("'") ? value + " " + token : token ; if(!value.contains("'") || value.endsWith("'")) { //Split the strings and get variables into hashmap attributes.put(value.split("=")[0].trim(),value.split("=")[1]); value =""; } } System.out.println(attributes); } output: {d=777, a=b, e='uij yyy', c='123 456'}In this case continuous space will be truncated to single space in the value. here attributed hashmap contains the values
ou, avec une regex pour la jeton et une petite machine à états qui ajoute simplement la clé / val à une carte: imprime p> Il effectue une vérification des erreurs de base et prend les guillemets hors des valeurs. p> p>
import java.io.*; import java.util.Scanner; public class ScanXan { public static void main(String[] args) throws IOException { Scanner s = null; try { s = new Scanner(new BufferedReader(new FileReader("<file name>"))); while (s.hasNext()) { System.out.println(s.next()); <write for output file> } } finally { if (s != null) { s.close(); } } } }
Oui @younghobbit Mon environnement de travail Linux (Ubuntu 15.01) codé sur sublime3.
Ne pouviez pas simplement utiliser une regex pour diviser par des espaces sauf si vous êtes à l'intérieur d'une citation (pas que je sais regex, mais je suis à peu près sûr que vous pouvez le faire).
Votre code fonctionne parfaitement ici à l'aide de JDK 1.6.0_13
@Lepad ci-dessus code donnera [a = b, c = '123, 456', D = 777, e = 'uij, yyy'] i>