2015-08-29 3 views
1

У меня есть строка, содержащая число. Что-то вроде "Incident #492 - The Title Description".
Мне нужно извлечь номер из этой строки.
ПробовалJava: необходимо извлечь номер из строки

Pattern p = Pattern.compile("\\d+"); 
Matcher m = p.matcher(theString); 
String substring =m.group(); 

Получая ошибку

java.lang.IllegalStateException: No match found 

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

+0

Можете ли вы утверждать, что не будет другие номера в String? – Tunaki

+0

Да, в моем случае есть только один, единственный номер. – Eliyahu

ответ

3

Вы получаете это исключение, потому что вам нужно вызвать find() на согласовани перед обращением group S:

Matcher m = p.matcher(theString); 
while (m.find()) { 
    String substring =m.group(); 
    System.out.println(substring); 
} 

Demo.

+0

Или 'matches()', если theString не допускаются посторонние символы. – Andreas

+1

@ Andreas Правильно. Однако строка OP позволяет использовать другие символы. – dasblinkenlight

0

Вы должны вызвать один из методов Matcher, например find, matches или lookingAt, чтобы фактически выполнить матч.

1

Есть две вещи неправильно здесь:

  • шаблон, который вы используете, не самый идеальный для вашего сценария, он проверяет только строку onl y содержит номера. Кроме того, поскольку он не содержит выражение группы, вызов group()is equivalent to calling group(0), which returns the entire string.

  • Вы должны быть уверены, что сличитель есть матч, прежде чем вы идете вызов группы.

Начнем с регулярного выражения. Вот как это выглядит сейчас.

Regular expression visualization

Debuggex Demo

Это будет только всегда соответствует строке, которая содержит все номера в нем.То, что вы заботитесь о конкретно число в этой строке, так что вы хотите выражение, которое:

  • не заботится о том, что перед ним
  • Не беспокойтесь о том, что это после того, как он
  • только матчи на одном случае чисел, и фиксирует его в группе

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

.*?(\\d+).* 

Regular expression visualization

Debuggex Demo

Последняя часть, чтобы гарантировать, что сличитель может найти матч, и что он получает правильную группу. Вот это достигается:

if (m.matches()) { 
    String substring = m.group(1); 
    System.out.println(substring); 
} 

Все вместе сейчас:

Pattern p = Pattern.compile(".*?(\\d+).*"); 
final String theString = "Incident #492 - The Title Description"; 
Matcher m = p.matcher(theString); 
if (m.matches()) { 
    String substring = m.group(1); 
    System.out.println(substring); 
} 
+0

Используемый шаблон OP на 100% прав, если вы не пытаетесь использовать 'matches()' на нем. Ему не нужен материал впереди или за частью '\\ d +', и ему не нужны группы, кроме группы по умолчанию, если только он не хочет захватывать другие части строки. – dasblinkenlight

+0

@dasblinkenlight: Я буду перефразировать его тогда - это не самое идеальное регулярное выражение для использования. Он будет работать до тех пор, пока вы используете 'find', но когда я создаю регулярные выражения, мне нравится, чтобы было ясно, что оно будет соответствовать * конкретным * вещам. – Makoto