web-dev-qa-db-fra.com

Comment faire correspondre des lettres uniquement à l'aide de Java regex, méthode matches?

import Java.util.regex.Pattern;

class HowEasy {
    public boolean matches(String regex) {
        System.out.println(Pattern.matches(regex, "abcABC   "));
        return Pattern.matches(regex, "abcABC");
    }

    public static void main(String[] args) {
        HowEasy words = new HowEasy();
        words.matches("[a-zA-Z]");
    }
}

La sortie est False. Où vais-je mal? Aussi, je veux vérifier si un mot ne contient que des lettres et peut ne pas se terminer par un seul point. Quelle est la regex pour cela?

c'est-à-dire "abc" "abc." est valide mais "abc .." n'est pas valide. 

Je peux utiliser la méthode indexOf() pour le résoudre, mais je veux savoir s'il est possible d'utiliser une seule expression régulière. 

19
user244333

"[a-zA-Z]" correspond à un seul caractère. Pour faire correspondre plusieurs caractères, utilisez "[a-zA-Z]+".

Puisqu'un point est un joker pour n'importe quel caractère, vous devez le masquer: "abc\." Pour rendre le point facultatif, vous avez besoin d'un point d'interrogation: "abc\.?" 

Si vous écrivez le modèle sous forme de constante littérale dans votre code, vous devez masquer la barre oblique inverse:

System.out.println ("abc".matches ("abc\\.?"));
System.out.println ("abc.".matches ("abc\\.?"));
System.out.println ("abc..".matches ("abc\\.?"));

Combinant les deux modèles:

System.out.println ("abc.".matches ("[a-zA-Z]+\\.?"));

Au lieu de a-zA-Z,\w est souvent plus approprié, car il capture des caractères étrangers comme äöüßø et ainsi de suite:

System.out.println ("abc.".matches ("\\w+\\.?"));   
39
user unknown

[A-Za-z ]* pour faire correspondre les lettres et les espaces.

6
kgautron

La méthode matches effectue une correspondance de la ligne complète, c'est-à-dire qu'elle équivaut à find() avec '^ abc $'. Donc, utilisez plutôt Pattern.compile("[a-zA-Z]").matcher(str).find() à la place. Ensuite, corrigez votre regex. Comme @user inconnu a été mentionné, votre expression rationnelle ne correspond à un caractère. Vous devriez probablement dire [a-zA-Z]+

3
AlexR

Trois problèmes ici:

  1. Il suffit d'utiliser String.matches() - si l'API est là, utilisez-le
  2. En Java, "match" signifie "correspond à l'entrée entière", ce qui est un contre-intuitif pour IMHO. Laissez donc l'API de votre méthode refléter cela en laissant les appelants penser à la correspondance de partie de l'entrée, comme le suggère votre exemple.
  3. Vous regex correspond à 1 seul caractère

Je vous recommande d'utiliser un code comme celui-ci:

public boolean matches(String regex) {
    regex = "^.*" + regex + ".*$"; // pad with regex to allow partial matching
    System.out.println("abcABC   ".matches(regex));
    return "abcABC   ".matches(regex);
}

public static void main(String[] args) {
    HowEasy words = new HowEasy();
    words.matches("[a-zA-Z]+"); // added "+" (ie 1-to-n of) to character class
}
0
Bohemian
import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStreamReader;
import Java.util.regex.*;

/* Write an application that prompts the user for a String that contains at least
 * five letters and at least five digits. Continuously re-Prompt the user until a
 * valid String is entered. Display a message indicating whether the user was
 * successful or did not enter enough digits, letters, or both.
 */
public class FiveLettersAndDigits {

  private static String readIn() { // read input from stdin
    StringBuilder sb = new StringBuilder();
    int c = 0;
    try { // do not use try-with-resources. We don't want to close the stdin stream
      BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
      while ((c = reader.read()) != 0) { // read all characters until null
        // We don't want new lines, although we must consume them.
        if (c != 13 && c != 10) {
          sb.append((char) c);
        } else {
          break; // break on new line (or else the loop won't terminate)
        }
      }
      // reader.readLine(); // get the trailing new line
    } catch (IOException ex) {
      System.err.println("Failed to read user input!");
      ex.printStackTrace(System.err);
    }

    return sb.toString().trim();
  }

  /**
   * Check the given input against a pattern
   *
   * @return the number of matches
   */
  private static int getitemCount(String input, String pattern) {
    int count = 0;

    try {
      Pattern p = Pattern.compile(pattern);
      Matcher m = p.matcher(input);
      while (m.find()) { // count the number of times the pattern matches
        count++;
      }
    } catch (PatternSyntaxException ex) {
      System.err.println("Failed to test input String \"" + input + "\" for matches to pattern \"" + pattern + "\"!");
      ex.printStackTrace(System.err);
    }

    return count;
  }

  private static String reprompt() {
    System.out.print("Entered input is invalid! Please enter five letters and five digits in any order: ");

    String in = readIn();

    return in;
  }

  public static void main(String[] args) {
    int letters = 0, digits = 0;
    String in = null;
    System.out.print("Please enter five letters and five digits in any order: ");
    in = readIn();
    while (letters < 5 || digits < 5) { // will keep occuring until the user enters sufficient input
      if (null != in && in.length() > 9) { // must be at least 10 chars long in order to contain both
        // count the letters and numbers. If there are enough, this loop won't happen again.
        letters = getitemCount(in, "[A-Za-z]");
        digits = getitemCount(in, "[0-9]");

        if (letters < 5 || digits < 5) {
          in = reprompt(); // reset in case we need to go around again.
        }
      } else {
        in = reprompt();
      }
    }
  }

}
0
Agi Hammerthief