Question

J'utilise Java Regexes en Java 1.6 (entre autres pour analyser la sortie numérique) et ne peut pas trouver une définition précise de \b ( « limite de mot »). Je l'avais supposé que -12 serait un « mot entier » (par correspondance \b\-?\d+\b) mais il semble que cela ne fonctionne pas. Je serais reconnaissant de connaître des méthodes permettant d'adapter les numéros séparés par des espaces.

Exemple:

Pattern pattern = Pattern.compile("\\s*\\b\\-?\\d+\\s*");
String plus = " 12 ";
System.out.println(""+pattern.matcher(plus).matches());
String minus = " -12 ";
System.out.println(""+pattern.matcher(minus).matches());
pattern = Pattern.compile("\\s*\\-?\\d+\\s*");
System.out.println(""+pattern.matcher(minus).matches());

retourne:

true
false
true
Était-ce utile?

La solution

Une limite de mot, dans la plupart des dialectes regex, est une position entre \w et \W (non-mot char), ou au début ou à la fin d'une chaîne si elle commence ou se termine (respectivement) avec un caractère de mot ([0-9A-Za-z_]) .

Ainsi, dans la "-12" chaîne, il correspond avant le 1 ou après le 2. Le tableau de bord est pas un caractère de mot.

Autres conseils

Une limite de mot peut se produire dans l'une des trois positions:

  1. Avant le premier caractère de la chaîne, si le premier caractère est un caractère de mot.
  2. Une fois le dernier caractère de la chaîne, si le dernier caractère est un caractère de mot.
  3. Entre deux caractères de la chaîne, où l'on est un caractère de mot et l'autre n'est pas un caractère de mot.

caractères de mots sont alphanumériques; un signe moins n'est pas. Tiré de Regex Tutorial .

Une limite de mot est une position qui est soit précédé d'un caractère de mot et non pas suivi par un, ou suivi d'un caractère de mot et non pas précédée par une.

Je parle de ce que les limites regex \b style sont en fait ici .

L'histoire courte est qu'ils sont conditionnel . Leur comportement dépend de ce qu'ils sont à côté.

# same as using a \b before:
(?(?=\w) (?<!\w)  | (?<!\W) )

# same as using a \b after:
(?(?<=\w) (?!\w)  | (?!\W)  )

Parfois, ce n'est pas ce que vous voulez. Voir mon autre réponse pour l'élaboration.

Consultez la documentation sur les conditions aux limites:

http://java.sun.com/docs /books/tutorial/essential/regex/bounds.html

Consultez cet exemple:

public static void main(final String[] args)
    {
        String x = "I found the value -12 in my string.";
        System.err.println(Arrays.toString(x.split("\\b-?\\d+\\b")));
    }

Lorsque vous l'imprimez, notez que la sortie est la suivante:

[J'ai trouvé la valeur -, dans ma chaîne.]

Cela signifie que le caractère « - » n'est pas repris comme étant à la limite d'un mot parce qu'il est pas considéré comme un caractère de mot. On dirait que @brianary m'a battu un peu à l'emporte-pièce, donc il obtient une mise à voix.

Je suis tombé sur un problème encore pire lorsque le texte recherche des mots comme .NET, C++, C# et C. On pourrait penser que les programmeurs informatiques connaîtraient mieux que de nommer une chose de la langue qui est difficile à écrire des expressions régulières pour.

Quoi qu'il en soit, ce que j'ai découvert (récapitulé la plupart du temps de http://www.regular-expressions.info , qui est un site): Dans la plupart des saveurs de regex, les caractères qui sont abondés par l'\w de classe de caractères sténographie sont les personnages qui sont traités comme des caractères de mot par des limites de mots. Java est une exception. Java prend en charge Unicode pour \b mais pas pour \w. (Je suis sûr qu'il y avait une bonne raison pour cela à l'époque).

Le \w signifie « caractère de mot ». Il correspond toujours les caractères ASCII [A-Za-z0-9_]. Notez l'inclusion du trait de soulignement et chiffres (mais pas dash!). Dans la plupart des saveurs qui prennent en charge Unicode, \w comprend de nombreux caractères d'autres scripts. Il y a beaucoup d'incohérence dont les caractères sont effectivement inclus. Les lettres et les chiffres de scripts et idéogrammes alphabétiques sont généralement inclus. Ponctuation de connecteur autre que le trait de soulignement et les symboles numériques qui ne sont pas les chiffres peuvent ou peuvent ne pas être inclus. XML Schema et XPath incluent même tous les symboles \w. Mais Java, JavaScript, et correspondre PCRE uniquement des caractères ASCII avec \w.

Quelle est la raison pour laquelle les recherches regex Java pour C++, C# ou .NET (même si vous vous souvenez d'échapper à la période et points positifs) sont vissés par le \b.

Note: Je ne sais pas quoi faire des erreurs dans le texte, comme quand quelqu'un ne met pas un espace après une période à la fin d'une phrase. Je le permettait, mais je ne suis pas sûr que ce soit nécessairement la bonne chose à faire.

Quoi qu'il en soit, en Java, si vous texte la recherche des ces langues étranges nommé, vous devez remplacer le \b avec avant et après désignateurs blancs et la ponctuation. Par exemple:

public static String grep(String regexp, String multiLineStringToSearch) {
    String result = "";
    String[] lines = multiLineStringToSearch.split("\\n");
    Pattern pattern = Pattern.compile(regexp);
    for (String line : lines) {
        Matcher matcher = pattern.matcher(line);
        if (matcher.find()) {
            result = result + "\n" + line;
        }
    }
    return result.trim();
}

Ensuite, dans votre test ou la fonction principale:

    String beforeWord = "(\\s|\\.|\\,|\\!|\\?|\\(|\\)|\\'|\\\"|^)";   
    String afterWord =  "(\\s|\\.|\\,|\\!|\\?|\\(|\\)|\\'|\\\"|$)";
    text = "Programming in C, (C++) C#, Java, and .NET.";
    System.out.println("text="+text);
    // Here is where Java word boundaries do not work correctly on "cutesy" computer language names.  
    System.out.println("Bad word boundary can't find because of Java: grep with word boundary for .NET="+ grep("\\b\\.NET\\b", text));
    System.out.println("Should find: grep exactly for .NET="+ grep(beforeWord+"\\.NET"+afterWord, text));
    System.out.println("Bad word boundary can't find because of Java: grep with word boundary for C#="+ grep("\\bC#\\b", text));
    System.out.println("Should find: grep exactly for C#="+ grep("C#"+afterWord, text));
    System.out.println("Bad word boundary can't find because of Java:grep with word boundary for C++="+ grep("\\bC\\+\\+\\b", text));
    System.out.println("Should find: grep exactly for C++="+ grep(beforeWord+"C\\+\\+"+afterWord, text));

    System.out.println("Should find: grep with word boundary for Java="+ grep("\\bJava\\b", text));
    System.out.println("Should find: grep for case-insensitive java="+ grep("?i)\\bjava\\b", text));
    System.out.println("Should find: grep with word boundary for C="+ grep("\\bC\\b", text));  // Works Ok for this example, but see below
    // Because of the stupid too-short cutsey name, searches find stuff it shouldn't.
    text = "Worked on C&O (Chesapeake and Ohio) Canal when I was younger; more recently developed in Lisp.";
    System.out.println("text="+text);
    System.out.println("Bad word boundary because of C name: grep with word boundary for C="+ grep("\\bC\\b", text));
    System.out.println("Should be blank: grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));
    // Make sure the first and last cases work OK.

    text = "C is a language that should have been named differently.";
    System.out.println("text="+text);
    System.out.println("grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

    text = "One language that should have been named differently is C";
    System.out.println("text="+text);
    System.out.println("grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

    //Make sure we don't get false positives
    text = "The letter 'c' can be hard as in Cat, or soft as in Cindy. Computer languages should not require disambiguation (e.g. Ruby, Python vs. Fortran, Hadoop)";
    System.out.println("text="+text);
    System.out.println("Should be blank: grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

P.S. Je tiens à remercier http://regexpal.com/ sans que le monde regex serait très malheureux!

Dans le cadre de l'apprentissage expression régulière, je suis vraiment coincé dans le métacaractère qui est \b. Je ne l'ai pas fait comprendre la signification alors que je me demandais « ce qu'il est, ce qu'il est » répétitivement. Après quelques tentatives en utilisant le site , je regarde les traits verticaux roses au tout début de mots et à la fin des mots. Je l'ai eu le sens bien à ce moment-là. Il est maintenant exactement mot (\w) intergranulaire .

Mon point de vue est que la compréhension orientée énormément. La logique derrière de celui-ci devrait être examinée d'une autre réponse.

Je voudrais expliquer la réponse de Alan Moore

  

Une limite de mot est une position qui est soit précédé d'un caractère de mot et non pas suivi par un, ou suivi d'un caractère de mot et non pas précédée par une.

Supposons que j'ai une chaîne "Ceci est c t et elle est wesome", et je suis censé remplacer tous occurance (s) la lettre « a » que si cette lettre existe au « Boundry d'un mot » à savoir la lettre a dans « chat » ne doit pas être remplacé.

Je vais effectuer regex ( Python ) comme

re.sub("\ba","e", myString.strip()) // remplacer a avec e

sortie sera Ceci est e c t end elle est ewesome

Je crois que votre problème est dû au fait que - est pas un caractère de mot. Ainsi, la limite de mot correspondra après la -, et ne sera donc pas le capturer. Les limites des mots correspondent avant la première et après les derniers caractères de mot dans une chaîne, ainsi que tout lieu où avant qu'il ne soit un caractère de mot ou un caractère non-mot, et après il est le contraire. Notez également que la limite de mot est un match nul largeur.

Une alternative possible est

(?:(?:^|\s)-?)\d+\b

Cela correspond à aucun numéros commençant par un espace et un tableau de bord en option, et se terminant à une limite de mot. Il correspondra également un numéro de départ au début de la chaîne.

Limite Word \ b est utilisé où un mot doit être un caractère de mot et un autre un caractère non-mot. Expression régulière pour nombre négatif doit être

--?\b\d+\b

DEMO

Je pense qu'il est la limite (à savoir le caractère suivant) du dernier match ou le début ou la fin de la chaîne.

lorsque vous utilisez \\b(\\w+)+\\b cela signifie correspondance exacte avec un mot contenant des caractères seulement mot ([a-zA-Z0-9])

dans votre cas, par exemple la mise en \\b au début de regex acceptera -12 (avec l'espace) mais encore une fois il n'acceptera -12 (sans espace)

pour référence pour soutenir mes mots: https: // docs. oracle.com/javase/tutorial/essential/regex/bounds.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top