Регулярное выражение для поиска чисел в строке



Я использую removeNumbers для удаления всех чисел в данной строке с помощью регулярного выражения
"(^| )\d+($|( \d+)+($| )| )"



Вот код:



public class Regex {    
private static String removeNumbers(String s) {
s = s.trim();
s = s.replaceAll(" +", " ");
s = s.replaceAll("(^| )\d+($|( \d+)+($| )| )", " ");
return s.trim();
}

public static void main(String[] args) {
String[] tests = new String[] {"123", "123 456 stack 789", "123 456 789 101112 131415 161718 192021", "stack 123 456 overflow 789 com", "stack 123 456 overflow 789", "123stack 456", "123 stack456overflow", "123 stack456", "123! @456#567"};
for (int i = 0; i < tests.length; i++) {
String test = tests[i];
System.out.println(""" + test + "" => "" + removeNumbers(test) + """);
}
}
}


Вывод :



"123" => ""
" 123 " => ""
"123 456 stack 789" => "stack"
"123 456 789 101112 131415 161718 192021" => ""
"stack 123 456 overflow 789 com" => "stack overflow com"
"stack 123 456 overflow 789" => "stack overflow"
"123stack 456" => "123stack"
"123 stack456overflow" => "stack456overflow"
"123 stack456" => "stack456"
"123! @456#567" => "123! @456#567"


Есть какой-нибудь лучший способ сделать это?



Edit:



Как было предложено @mbomb007 в его предыдущем ответе, регулярное выражение "( |^)[\d ]+( |$)" также работает:



private static String removeNumbers(String s) {
s = s.trim();
s = s.replaceAll(" +", " ");
s = s.replaceAll("( |^)[\d ]+( |$)", " ");
return s.trim();
}
461   3  

3 ответов:

AFAIU, вы можете просто сделать:

private static String removeNumbers(String s) {
    return s.replaceAll("\\b\\d+\\b", "").replaceAll(" +", " ").trim();
}

\b\d+\b соответствует одной или нескольким цифрам, образующим слово.

Редактировать:

Поскольку шаблон не должен совпадать с числами в строке типа "123! @456#567", можно использовать комбинацию положительных условий lookbehind и lookahead:

private static String removeNumbers(String s) {
    return s.replaceAll("(?<= |^)\\d+(?= |$)", " ").replaceAll(" +", " ").trim();
}

Ваше регулярное выражение немного избыточно (и также не совсем соответствует вашим тестовым случаям). Вы можете использовать это:

"\\b[ ]*(?<![^\\d\\s])[\\d]+(?![^\\d\\s])[ ]*\\b"

Escape-символ \b представляет границу слова (начало или конец слова). Я также использую [ ]*, чтобы обеспечить удаление пробелов между числами. Это регулярное выражение также позволяет словам содержать числа без их замены. Именно так, как ты хочешь.

EDIT : я добавил отрицательный lookbehind и положительный lookahead.

(?<![^\\d\\s]) - это гарантирует, что символы, непосредственно предшествующие цифрам, - это только дополнительные цифры или пробелы.

(?![^\\d\\s]) - это гарантирует, что символы, непосредственно следующие за цифрами, являются только дополнительными цифрами или пробелами.

Попробуйте здесь с вашими тестовыми случаями. (Обновлена гиперссылка для добавленного тестового случая)

Вы также можете сделать это с помощью библиотеки guava:

 String text = "stack 123 456 overflow 789 com";
 String theLettersWithLargeSpaces = CharMatcher.JAVA_LETTER.or(CharMatcher.WHITESPACE).retainFrom(text); 
 theLetters = CharMatcher.WHITESPACE.collapseFrom(theLettersWithLargeSpaces , ' ');
 System.out.println(theLetters);
Я предположил, что могут встречаться не только цифры, но и другие нежелательные символы. Вывод будет следующим: "Stack overflow com"

CharMatcher-это очень мощный инструмент. Я думаю, что это гораздо более читабельно, чем регулярные выражения.

Если вы хотите просто функцию:

public String clearUnwantedChars(String text) {
      return CharMatcher.WHITESPACE.collapseFrom(CharMatcher.JAVA_LETTER.or(CharMatcher.WHITESPACE)
            .retainFrom(text), ' ');
}

Comments

    Ничего не найдено.