Извлечь ISBN с помощью регулярного выражения - PullRequest
4 голосов
/ 19 августа 2011

У меня очень длинная строка, которую я хочу проанализировать для числового значения, которое появляется после подстроки "ISBN".Тем не менее, эта группа из 13 цифр может быть организована по-разному с помощью символа «-».Примеры: (все это действительные номера ISBN) 123-456-789-123-4, OR 1-2-3-4-5-67891234, OR 12-34-56-78-91-23-4.По сути, я хочу использовать шаблон соответствия регулярных выражений на потенциальном ISBN, чтобы увидеть, существует ли действительный 13-значный ISBN.Как «игнорировать» символ «-», чтобы я мог просто выполнить регулярное выражение для шаблона \d{13}?Моя функция:

public String parseISBN (String sourceCode) {
  int location = sourceCode.indexOf("ISBN") + 5;
  String ISBN = sourceCode.substring(location); //substring after "ISBN" occurs
  int i = 0;
  while ( ISBN.charAt(i) != ' ' )
    i++;
  ISBN = ISBN.substring(0, i); //should contain potential ISBN value
  Pattern pattern = Pattern.compile("\\d{13}"); //this clearly will find 13 consecutive numbers, but I need it to ignore the "-" character
  Matcher matcher = pattern.matcher(ISBN); 
  if (matcher.find()) return ISBN;
  else return null;
}

Ответы [ 7 ]

8 голосов
/ 19 августа 2011
  • Альтернатива 1:

    pattern.matcher(ISBN.replace("-", ""))
    
  • Альтернатива 2: что-то вроде

    Pattern.compile("(\\d-?){13}")
    

Демо второй альтернативы:

String ISBN = "ISBN: 123-456-789-112-3, ISBN: 1234567891123";

Pattern pattern = Pattern.compile("(\\d-?){13}");
Matcher matcher = pattern.matcher(ISBN);

while (matcher.find())
    System.out.println(matcher.group());

Выход:

123-456-789-112-3
1234567891123
5 голосов
/ 19 августа 2011

Попробуйте это:

Pattern.compile("\\d(-?\\d){12}")
3 голосов
/ 19 августа 2011

Используйте этот шаблон:

Pattern.compile("(?:\\d-?){13}")

и уберите все тире из найденного номера isbn

2 голосов
/ 19 августа 2011

Если вы собираетесь часто вызывать метод, лучшее, что вы можете сделать, это , а не , скомпилировать шаблон внутри него. В противном случае, каждый раз, когда вы вызываете метод, вы тратите больше времени на создание регулярного выражения, чем на его поиск.

Но, посмотрев на ваш код еще раз, я думаю, что у вас есть большая проблема с точки зрения производительности. Все, что нужно для поиска «ISBN» и создания подстрок для применения регулярных выражений, совершенно не нужно. Позвольте регулярному выражению делать это; это то, для чего они. Следующее регулярное выражение находит "ISBN" дозорного и следующие тринадцать цифр, если они там есть:

static final Pattern isbnPattern = Pattern.compile(
    "\\bISBN[^A-Z0-9]*+(\\d(?:-*+\\d){12})", Pattern.CASE_INSENSITIVE );

[^A-Z0-9]*+ поглощает любые символы, которые могут появиться между "ISBN" и первой цифрой. Собственный квантификатор (*+) предотвращает ненужный возврат; если следующий символ не является цифрой, механизм регулярных выражений немедленно завершает эту попытку сопоставления и возобновляет сканирование для другого экземпляра «ISBN».

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

public String parseISBN (String source) {
  Matcher m = isbnPattern.matcher(source); 
  return m.find() ? m.group(1) : null;
}

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

2 голосов
/ 19 августа 2011

Сделайте это за один шаг с шаблоном, распознающим все, и дополнительными тире между цифрами Не нужно возиться со смещением ISBN + подстроки.

ISBN(\d(-?\d){12})

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

1 голос
/ 19 августа 2011

Вы можете удалить штрихи с помощью манипуляции со строкой, или вы можете использовать это:

"\\b(?:\\d-?){13}\\b"

У него есть дополнительный бонус: строка не начинается и не заканчивается -.

0 голосов
/ 19 августа 2011

Попробуйте убрать тире и откорректировать новую строку

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...