Ваши ".*"
шаблоны являются жадными, как и их привычка, и поглощают столько, сколько могут - что будет всей цепочкой. Так что первый ".*"
соответствует всей строке, оставляя спорный спор. Кроме того, в ваших "\\d?"
предложениях указывается одна цифра, которая является необязательной, ни одна из которых не является той, которую вы хотите.
Это, вероятно, больше соответствует тому, за что вы стреляете:
Pattern stringWith2Numbers = Pattern.compile(".*?(\\d+).*?(\\d+).*?");
Конечно, раз уж вы не заботитесь о вещах до или после чисел, зачем их беспокоить?
Pattern stringWith2Numbers = Pattern.compile("(\\d+).*?(\\d+)");
Это должно сработать.
Редактировать: Не торопясь с написанием потрясающе классных комиксов, Алан Мур указал на некоторые проблемы с моим решением в комментариях. Для начала, если у вас есть только одно многозначное число в строке, мое решение ошибочно. Применение его к «This 123 is bad string» приведет к тому, что он вернет «12» и «3», когда он должен просто потерпеть неудачу. Лучшее регулярное выражение будет предусматривать, что ДОЛЖЕН быть хотя бы один нецифровый символ, разделяющий два числа, например так:
Pattern stringWith2Numbers = Pattern.compile("(\\d+)\\D+(\\d+)");
Кроме того, matches()
применяет шаблон ко всей строке , заключая его в скобки в ^
и $
; find()
сделает трюк, но это не то, что использовал ОП. Так что придерживаясь matches()
, нам нужно вернуть эти «бесполезные» предложения перед двумя числами и после них. (Хотя лучше явно указывать их без цифр, а не с подстановочными знаками.) Так это будет выглядеть так:
Pattern stringWith2Numbers = Pattern.compile("\\D*(\\d+)\\D+(\\d+)\\D*");
... что, надо заметить, чертовски близко к ответу jjnguy.