Actuellement (dernier test sur Java 17), il est possible de le faire avec split()
mais dans le monde réel, n'utilisez pas cette approche car elle semble être basée sur un bogue, puisque le look-behind en Java devrait avoir une longueur maximale évidente. \w+
qui ne respecte pas cette limitation et qui, d'une manière ou d'une autre, fonctionne toujours. S'il s'agit d'un bogue qui sera corrigé dans les versions ultérieures, cette solution cessera de fonctionner.
Utilisez plutôt Pattern
y Matcher
avec des expressions rationnelles comme \w+\s+\w+
qui, en plus d'être plus sûr, évite l'enfer de la maintenance pour les personnes qui hériteront de ce code (n'oubliez pas de " Toujours coder comme si la personne qui finit par maintenir votre code est un psychopathe violent qui sait où vous vivez. ").
Est-ce que c'est ce que vous recherchez ?
(vous pouvez remplacer <code>\w</code> avec <code>\S</code> pour inclure tous les caractères qui ne sont pas des espaces, mais pour cet exemple je laisserai <code>\w</code> puisqu'il est plus facile de lire les expressions rationnelles avec <code>\w\s</code> entonces <code>\S\s</code> )
String input = "one two three four five six seven";
String[] pairs = input.split("(?<!\\G\\w+)\\s");
System.out.println(Arrays.toString(pairs));
sortie :
[one two, three four, five six, seven]
\G
est la correspondance précédente, (?<!regex)
est un regard négatif en arrière.
Sur split
nous essayons de
- trouver des espaces ->
\\s
- qui ne sont pas prédits ->
(?<!negativeLookBehind)
- par un mot ->
\\w+
- avec le précédemment apparié (espace) ->
\\G
- avant qu'il ->
\\G\\w+
.
La seule confusion que j'ai eue au début était de savoir comment cela fonctionnerait pour le premier espace puisque nous voulons que cet espace soit ignoré. Une information importante est que \\G
au début correspond au début de la chaîne ^
.
Ainsi, avant la première itération, la regex en look-behind négatif ressemblera à ceci (?<!^\\w+)
et depuis le premier espace faire ont ^\\w+
avant, ça ne peut pas correspondre à la division. L'espace suivant n'aura pas ce problème, il sera donc mis en correspondance et les informations le concernant (comme son numéro d'immatriculation) seront prises en compte. position en input
String) sera stocké dans \\G
et utilisé plus tard dans le prochain look-behind négatif.
Ainsi, pour le troisième espace, la regex vérifiera s'il y a un espace correspondant précédemment. \\G
et le mot \\w+
avant lui. Puisque le résultat de ce test sera positif, le look-behind négatif ne l'acceptera pas et cet espace ne sera pas apparié, mais le 4ème espace n'aura pas ce problème parce que l'espace qui le précède ne sera pas le même que celui stocké en \\G
(il aura une position différente dans input
String).
De même, si quelqu'un souhaite se séparer, disons, d'un espace sur trois, il peut utiliser ce formulaire (basé sur le principe de la séparation des espaces). @maybeWeCouldStealAVan 's respuesta qui a été supprimé lorsque j'ai posté ce fragment de réponse)
input.split("(?<=\\G\\w{1,100}\\s\\w{1,100}\\s\\w{1,100})\\s")
Au lieu de 100, vous pouvez utiliser une valeur plus grande qui sera au moins égale à la longueur du mot le plus long de la chaîne.
Je viens de remarquer que l'on peut aussi utiliser +
au lieu de {1,maxWordLength}
si nous voulons diviser avec chaque nombre impair comme chaque 3ème, 5ème, 7ème par exemple.
String data = "0,0,1,2,4,5,3,4,6,1,3,3,4,5,1,1";
String[] array = data.split("(?<=\\G\\d+,\\d+,\\d+,\\d+,\\d+),");//every 5th comma
7 votes
Pourquoi ? Est-ce un puzzle ou un réel problème ?
3 votes
C'est une énigme... mais cela m'a suffisamment intéressé pour la poser, parce que les look-behinds doivent être de longueur limitée, donc cela semble être un problème non trivial.
3 votes
+1. Question très intéressante.
4 votes
Le look-behind de Java est une bête des plus étranges. Dans .NET, vous pouvez librement faire un look-behind pour une longueur variable. Dans PCRE, vous pouvez seulement regarder derrière vous pour une longueur fixe. En Java, en raison d'un bogue/caractéristique dans l'implémentation de la fonction
+
y*
vous parfois peut correspondre à un motif de longueur variable : stackoverflow.com/questions/1536915/