Как сопоставить буквы только с помощью регулярных выражений Java, метод соответствия? - PullRequest
20 голосов
/ 23 октября 2011
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]");
    }
}

Вывод False. Куда я иду не так? Также я хочу проверить, содержит ли слово только буквы и может или не может заканчиваться одним периодом. Что такое регулярное выражение для этого?

т.е. "abc" "abc." допустимо, но "abc .." недействительно.

Я могу использовать метод indexOf() для ее решения, но я хочу знать, возможно ли использовать одно регулярное выражение.

Ответы [ 5 ]

40 голосов
/ 23 октября 2011

"[a-zA-Z]" соответствует только одному символу. Чтобы сопоставить несколько символов, используйте "[a-zA-Z]+".

Поскольку точка является джокером для любого персонажа, вы должны замаскировать ее: "abc\." Чтобы сделать точку необязательной, вам нужен знак вопроса: "abc\.?"

Если вы пишете Pattern как константу литерала в своем коде, вы должны замаскировать обратную косую черту:

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

Объединение обоих шаблонов:

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

Вместо a-zA-Z часто более подходящим является \ w, поскольку он фиксирует иностранные символы, такие как äöüßø и т. Д.:

System.out.println ("abc.".matches ("\\w+\\.?"));   
6 голосов
/ 23 октября 2011

[A-Za-z ]* для сопоставления букв и пробелов.

3 голосов
/ 23 октября 2011
Метод

matches выполняет сопоставление полной строки, т. Е. Он эквивалентен find() с '^ abc $'. Так что просто используйте Pattern.compile("[a-zA-Z]").matcher(str).find() вместо этого. Затем исправьте свое регулярное выражение. Как упомянул @user unknown, ваше регулярное выражение соответствует только одному символу. Вы, вероятно, должны сказать [a-zA-Z]+

0 голосов
/ 03 января 2019
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 голосов
/ 23 октября 2011

Три проблемы здесь:

  1. Просто используйте String.matches() - если API есть, используйте его
  2. В java "совпадения" означают "совпадения всего ввода", что IMHO нелогично, поэтому позвольте API вашего метода отразить это, позволяя вызывающим абонентам думать о сопоставлении part of вход, как показывает ваш пример
  3. Вы regex соответствует только 1 символу

Я рекомендую использовать такой код:

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...