Regex correspondant aux espaces-Java


L'API Java pour expressions régulières indique que \s correspondra aux espaces. Donc, l'expression régulière \\s\\s doit correspondre à deux espaces.

Pattern whitespace = Pattern.compile("\\s\\s");
matcher = whitespace.matcher(modLine);
while (matcher.find()) matcher.replaceAll(" ");

Le but est de remplacer toutes les instances de deux espaces consécutifs par un seul espace. Cependant, ce n'est pas réellement le travail.

Ai-je un grave malentendu sur les expressions rationnelles ou le terme "espace blanc"?

Author: Glenn Nelson, 2011-01-19

8 answers

Ouais, vous devez saisir le résultat de matcher.replaceAll ():

String result = matcher.replaceAll(" ");
System.out.println(result);
 38
Author: Raph Levien, 2011-01-19 02:02:25

Vous ne pouvez pas utiliser \sen Java pour faire correspondre les espaces blancs sur son propre jeu de caractères natif, car Java ne prend pas en charge la propriété Unicode white space - même si cela est strictement requis pour répondre à la RL1.2 de UTS#18! Ce qu'il a n'est pas conforme aux normes, hélas.

Unicode définit 26 points de code comme \p{White_Space}: 20 d'entre eux sont différentes sortes de \pZ GeneralCategory=Separator, et les 6 autres sont \p{Cc} GeneralCategory=Control.

L'espace blanc est une propriété assez stable, et ces mêmes ont été autour pratiquement pour toujours. Malgré cela, Java n'a pas de propriété conforme à la norme Unicode pour ceux-ci, vous devez donc utiliser du code comme ceci:

String whitespace_chars =  ""       /* dummy empty string for homogeneity */
                        + "\\u0009" // CHARACTER TABULATION
                        + "\\u000A" // LINE FEED (LF)
                        + "\\u000B" // LINE TABULATION
                        + "\\u000C" // FORM FEED (FF)
                        + "\\u000D" // CARRIAGE RETURN (CR)
                        + "\\u0020" // SPACE
                        + "\\u0085" // NEXT LINE (NEL) 
                        + "\\u00A0" // NO-BREAK SPACE
                        + "\\u1680" // OGHAM SPACE MARK
                        + "\\u180E" // MONGOLIAN VOWEL SEPARATOR
                        + "\\u2000" // EN QUAD 
                        + "\\u2001" // EM QUAD 
                        + "\\u2002" // EN SPACE
                        + "\\u2003" // EM SPACE
                        + "\\u2004" // THREE-PER-EM SPACE
                        + "\\u2005" // FOUR-PER-EM SPACE
                        + "\\u2006" // SIX-PER-EM SPACE
                        + "\\u2007" // FIGURE SPACE
                        + "\\u2008" // PUNCTUATION SPACE
                        + "\\u2009" // THIN SPACE
                        + "\\u200A" // HAIR SPACE
                        + "\\u2028" // LINE SEPARATOR
                        + "\\u2029" // PARAGRAPH SEPARATOR
                        + "\\u202F" // NARROW NO-BREAK SPACE
                        + "\\u205F" // MEDIUM MATHEMATICAL SPACE
                        + "\\u3000" // IDEOGRAPHIC SPACE
                        ;        
/* A \s that actually works for Java’s native character set: Unicode */
String     whitespace_charclass = "["  + whitespace_chars + "]";    
/* A \S that actually works for  Java’s native character set: Unicode */
String not_whitespace_charclass = "[^" + whitespace_chars + "]";

Maintenant, vous pouvez utiliser whitespace_charclass + "+", comme le motif dans votre replaceAll.


=begin soapbox

Désolé pour tout ça. Les expressions régulières de Java ne fonctionnent tout simplement pas très bien sur son propre jeu de caractères natif, et vous devez donc vraiment passer par exotic cerceaux pour les faire travailler.

Et si vous pensez que l'espace blanc est mauvais, vous devriez voir ce que vous devez faire pour que \w et \b se comportent enfin correctement!

Oui, c'est possible, et oui, c'est un gâchis mindnumbing. C'est être charitable, même. Le moyen le plus simple d'obtenir une bibliothèque regex standard-comforming pour Java est de JNI sur les trucs d'ICU. C'est ce que Google fait pour Android, car OraSun ne mesure pas.

Si vous ne voulez pas le faire, mais encore envie de restez avec Java, j'ai une bibliothèque de réécriture regex frontal J'ai écrit que "corrige" les modèles de Java, au moins pour les rendre conformes aux exigences de RL1.2a dans UTS # 18, Expressions régulières Unicode.

=end soapbox

 162
Author: tchrist, 2011-04-12 00:39:04

Pour Java (pas php, pas javascript, pas anyother):

txt.replaceAll("\\p{javaSpaceChar}{2,}"," ")
 8
Author: surfealokesea, 2013-06-11 16:11:53

Semble fonctionner pour moi:

String s = "  a   b      c";
System.out.println("\""  + s.replaceAll("\\s\\s", " ") + "\"");

Imprimera:

" a  b   c"

Je pense que vous aviez l'intention de le faire au lieu de votre code:

Pattern whitespace = Pattern.compile("\\s\\s");
Matcher matcher = whitespace.matcher(s);
String result = "";
if (matcher.find()) {
    result = matcher.replaceAll(" ");
}

System.out.println(result);
 4
Author: Mihai Toader, 2011-01-19 02:01:51

Lorsque j'ai envoyé une question à un forum Regexbuddy (regex developer application), j'ai eu une réponse plus exacte à ma question Java:

"Auteur du message: Jan Goyvaerts

En Java, les raccourcis \s, \d et \w incluent uniquement les caractères ASCII. ... Ce n'est pas un bogue en Java, mais simplement l'une des nombreuses choses dont vous devez être conscient lorsque vous travaillez avec des expressions régulières. Pour faire correspondre tous les espaces Unicode ainsi que les sauts de ligne, vous pouvez utiliser [\s\p{Z}] en Java. RegexBuddy ne le fait pas encore prend en charge les propriétés spécifiques à Java telles que \p{javaSpaceChar} (qui correspond exactement aux mêmes caractères que [\s\p{Z}]).

... \s \ s correspondra à deux espaces, si l'entrée est ASCII uniquement. Le vrai problème est avec le code de l'OP, comme le souligne la réponse acceptée dans cette question."

 4
Author: Tuomas, 2014-11-03 12:01:11
Pattern whitespace = Pattern.compile("\\s\\s");
matcher = whitespace.matcher(modLine);

boolean flag = true;
while(flag)
{
 //Update your original search text with the result of the replace
 modLine = matcher.replaceAll(" ");
 //reset matcher to look at this "new" text
 matcher = whitespace.matcher(modLine);
 //search again ... and if no match , set flag to false to exit, else run again
 if(!matcher.find())
 {
 flag = false;
 }
}
 1
Author: Mike, 2011-09-15 12:51:05

Pour votre usage, vous pouvez utiliser ce snnippet:

import org.apache.commons.lang3.StringUtils;
StrintUtils.StringUtils.normalizeSpace(string);

Cela normalisera l'espacement en simple et supprimera également les espaces blancs de début et de fin.

 0
Author: Rashid Mv, 2018-05-18 19:42:30

L'utilisation d'espaces dans RE est une douleur, mais je crois qu'ils fonctionnent. Le problème de l'OP peut également être résolu en utilisant StringTokenizer ou la méthode split (). Cependant, pour utiliser RE (décommentez println () pour voir comment le matcher décompose la chaîne), voici un exemple de code:

import java.util.regex.*;

public class Two21WS {
    private String  str = "";
    private Pattern pattern = Pattern.compile ("\\s{2,}");  // multiple spaces

    public Two21WS (String s) {
            StringBuffer sb = new StringBuffer();
            Matcher matcher = pattern.matcher (s);
            int startNext = 0;
            while (matcher.find (startNext)) {
                    if (startNext == 0)
                            sb.append (s.substring (0, matcher.start()));
                    else
                            sb.append (s.substring (startNext, matcher.start()));
                    sb.append (" ");
                    startNext = matcher.end();
                    //System.out.println ("Start, end = " + matcher.start()+", "+matcher.end() +
                    //                      ", sb: \"" + sb.toString() + "\"");
            }
            sb.append (s.substring (startNext));
            str = sb.toString();
    }

    public String toString () {
            return str;
    }

    public static void main (String[] args) {
            String tester = " a    b      cdef     gh  ij   kl";
            System.out.println ("Initial: \"" + tester + "\"");
            System.out.println ("Two21WS: \"" + new Two21WS(tester) + "\"");
}}

Il produit ce qui suit (compiler avec javac et exécuter à l'invite de commande):

% java Two21WS Initiale: "a b cdef gh ij kl" 21ws: "a b cdef gh ij kl"

 -3
Author: Manidip Sengupta, 2011-01-19 04:10:51