272 votes

Comment diviser une chaîne tout en conservant les délimiteurs?

J'ai une multiligne chaîne qui est délimitée par un ensemble de différents délimiteurs:

(Text1)(DelimiterA)(Text2)(DelimiterC)(Text3)(DelimiterB)(Text4)

Je peux diviser cette chaîne en ses parties, à l'aide de String.split, mais il semble que je ne peux pas obtenir de la chaîne, ce qui correspondait à la délimiteur de regex.

En d'autres termes, c'est ce que j'obtiens:

  • Text1
  • Text2
  • Text3
  • Text4

C'est ce que je veux

  • Text1
  • DelimiterA
  • Text2
  • DelimiterC
  • Text3
  • DelimiterB
  • Text4

Est-il un JDK façon de diviser la chaîne en utilisant un séparateur de regex mais aussi de garder les délimiteurs?

346voto

NawaMan Points 10266

Vous pouvez utiliser d'Anticipation et Lookbehind. Comme ceci:

System.out.println(Arrays.toString("a;b;c;d".split("(?<=;)")));
System.out.println(Arrays.toString("a;b;c;d".split("(?=;)")));
System.out.println(Arrays.toString("a;b;c;d".split("((?<=;)|(?=;))")));

Et vous obtiendrez:

[a;, b;, c;, d]
[a, ;b, ;c, ;d]
[a, ;, b, ;, c, ;, d]

Le dernier est ce que vous voulez.

((?<=;)|(?=;)) équivaut à sélectionner un de caractères vide avant d' ; ou après l' ;.

Espérons que cette aide.

EDIT Fabian Steeg commentaires sur la Lisibilité est valide. La lisibilité est toujours le problème de RegEx. Une chose, je le fais à l'aide d'assouplissement c'est de créer une variable dont le nom représente la regex ne et de l'utilisation de Java format de Chaîne de caractères pour l'aider. Comme ceci:

static public final String 

Cela aide un peu. :-D

30voto

chillysapien Points 1211

Une solution très naïve, sans regex, consisterait à remplacer le délimiteur par une chaîne de la manière suivante (en supposant une virgule pour le délimiteur):

 string.replace(FullString, "," , "~,~")
 

Où vous pouvez remplacer tilda (~) par un délimiteur unique approprié.

Ensuite, si vous divisez votre nouveau délimiteur, je pense que vous obtiendrez le résultat souhaité.

1voto

Fabian Steeg Points 24261

Je ne pense pas que ce soit possible avec String#split , mais vous pouvez utiliser un StringTokenizer , bien que cela ne vous permette pas de définir votre délimiteur en tant que regex, mais uniquement en tant que classe. de caractères à un chiffre:

 new StringTokenizer("Hello, world. Hi!", ",.!", true); // true for returnDelims
 

1voto

Steve McLeod Points 19016

Je suggère d'utiliser Pattern and Matcher, qui donnera presque certainement ce que vous voulez. Votre expression régulière devra être un peu plus compliquée que ce que vous utilisez dans String.split.

0voto

Varun Gangal Points 81

Une solution extrêmement naïve et inefficace qui fonctionne quand même. Utilisez split deux fois sur la chaîne, puis concaténez les deux tableaux.

 String temp[]=str.split("\\W");
String temp2[]=str.split("\\w||\\s");
int i=0;
for(String string:temp)
System.out.println(string);
String temp3[]=new String[temp.length-1];
for(String string:temp2)
{
        System.out.println(string);
        if((string.equals("")!=true)&&(string.equals("\\s")!=true))
        {
                temp3[i]=string;
                i++;
        }
//      System.out.println(temp.length);
//      System.out.println(temp2.length);
}
System.out.println(temp3.length);
String[] temp4=new String[temp.length+temp3.length];
int j=0;
for(i=0;i<temp.length;i++)
{
        temp4[j]=temp[i];
        j=j+2;
}
j=1;
for(i=0;i<temp3.length;i++)
{
        temp4[j]=temp3[i];
        j+=2;
}
for(String s:temp4)
System.out.println(s);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X