Как вернуть первый фрагмент цифр или букв из строки?

#java #regex #string

#java #регулярное выражение #строка

Вопрос:

Например, если бы у меня было (-> означает возврат):

 aBc123afa5  ->  aBc

168dgFF9g  ->  168

1GGGGG  ->  1
 

Как я могу это сделать на Java? Я предполагаю, что это связано с регулярными выражениями, но я не очень разбираюсь в регулярных выражениях и поэтому не слишком уверен, как это реализовать (я мог бы немного подумать, но у меня такое чувство, что это будет 5-10 строк, и я думаю, что это можно было бы сделать однострочным).

Спасибо

Комментарии:

1. вы хотели текст после -> ?

2. 3-й случай не может правильно понять

3. да, извините, я хочу текст после ->

4. Будет ли это работать для вас? /^([a-zA-Z] |[0-9] )/

Ответ №1:

 String myString = "aBc123afa5";
String extracted = myString.replaceAll("^([A-Za-z] |\d ).*$", "$1");
 

Посмотрите демонстрацию регулярных выражений и демонстрацию кода в реальном времени!

Использовать Matcher.group() и повторно использовать a Pattern для повышения эффективности:

 // Class
private static final Pattern pattern = Pattern.compile("^([A-Za-z] |\d ).*$");

// Your method
{
    String myString = "aBc123afa5";
    Matcher matcher = pattern.matcher(myString);
    if(matcher.matches())
        System.out.println(matcher.group(1));
}
 

Примечание: /^([A-Za-z] |d ).*$ и /^([A-Za-z] |d )/ оба работают с одинаковой эффективностью. В regex101 вы можете сравнить журналы отладки matcher, чтобы выяснить это.

Ответ №2:

Вы можете сделать это без использования регулярных выражений:

 String string = "168dgFF9g";
String chunk = ""   string.charAt(0);
boolean searchDigit = Character.isDigit(string.charAt(0));
for (int i = 1; i < string.length(); i  ) {
  boolean isDigit = Character.isDigit(string.charAt(i));
  if (isDigit == searchDigit) {
    chunk  = string.charAt(i);
  } else {
    break;
  }
}
System.out.println(chunk);
 

Комментарии:

1. В этом случае (без каламбура) было бы лучше использовать регулярное выражение, а не цикл, и я хотел бы отметить, что вторая строка была бы оптимальной при использовании String chunk = Character.toString( string.charAt(0) ); .

2. Да, верно. Это всего лишь альтернативное решение, поскольку OP не очень удобен с регулярными выражениями.

Ответ №3:

 public static String prefix(String s) {
    return s.replaceFirst("^(\d |\pL |).*$", "$1");
}
 

где

 \d  = digit
\pL = letter
postfix   = one or more
|    = or
^    = begin of string
$    = end of string
$1   = first group `( ... )`
 

Пустая альтернатива (последняя | ) гарантирует, что (...) она всегда совпадает, и всегда происходит замена. В противном случае будет возвращена исходная строка.

Комментарии:

1. Повысит ли производительность использование .replaceFirst() вместо .replaceAll() из моего решения? У меня всегда была тенденция использовать .replaceAll() в своем коде, поэтому мне это интересно.

2. Здесь вы хотите один раз извлечь (начальную) строку из отверстия. И на самом деле выбросить все остальное. Если вы видите a "^...$" , ясно, что все сопоставлено и replaceFirst имеет смысл только. Но да, всегда нужно позаботиться о таком маленьком решении.