Почему это регулярное выражение терпит неудачу в одном случае использования - текстовой строке, содержащей амперсанд? - PullRequest
1 голос
/ 19 октября 2010

Я пытаюсь найти регулярное выражение , чтобы отделить информацию об авторе и названии книги от набора данных.

Кажется, этот работает нормально:

^\s*(?:(.*)\s+-\s+)?'?([^']+'?.*)\s*$

На приведенных ниже данных идентифицирует автора в group 1 как текст, предшествующий первому дефису, и, в случае отсутствия дефиса, идентифицирует название книги в group 2

William Faulkner - 'Light In August'
William Faulkner - 'Sanctuary'
William Faulkner - 'The Sound and the Fury'
Saki - 'Esme'
Saki - 'The Unrest Cure' (Second Edition)
Saki (File Under: Hector Hugh Munro) - 'The Interlopers' (Anniversary Multi-pack)
William Faulkner - 'The Sound and the Fury' (Collector's Re-issue)
'The Sound and the Fury'
The Sound and the Fury
The Bible (St James Version)

Однако, в случае следующей строки, содержащей амперсанд, происходит сбой:

'Jim Clarke & Oscar Wilde'

Может ли кто-нибудь объяснить, почему это здесь не работает?

UPDATE:

Вот соответствующий код Java:

Pattern pattern = Pattern.compile("^\\s*(?:(.*)\\s+-\\s+)?'?([^']+'?.*)\\s*$");
Matcher matcher = pattern.matcher(text);
if(!matcher.matches()) 
{
    logFailure(text);
}
else
{
    String author = matcher.group(1).trim();
    String bookTitle = matcher.group(2).trim();
}

A NullPointerException добавляется в следующей строке из приведенной выше выдержки:

    String author = matcher.group(1).trim();

Ответы [ 3 ]

2 голосов
/ 19 октября 2010

matcher.group(1) возвращает ноль, когда у вас нет дефиса, поэтому .trim() выбрасывает NPE.

Ваше текущее регулярное выражение также съедает первую найденную им одиночную кавычку.Кроме того, вы действительно хотите не совпадать?Вы просто заходите туда.Если text на самом деле не должен соответствовать шаблону, вы можете использовать более простой алгоритм.

int hyphenIndex = text.indexOf("-");
if (hyphenIndex > -1) {
    String author = text.substring(0, hyphenIndex);
    System.out.println(author);
}
String title = text.substring(hyphenIndex + 1, text.length());
System.out.println(title);

Однако, если вам требуется отклонить определенные строки, возможно, есть несколько вещей, которые вы могли бы сделать, чтобы сделать это также более читабельным.1012 * и звоните pattern.matcher(text.trim())

1 голос
/ 19 октября 2010

Ваш Regex работает нормально, просто в приведенном вами примере нет автора, поэтому первая подходящая группа пуста. Поэтому, когда вы пытаетесь вызвать matcher.group (1) .trim (), вы получаете NPE.

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

String author = matcher.group(1);
if(author == null) {
  author = "";
}
author = author.trim();
1 голос
/ 19 октября 2010

group (1) может возвращать ноль, вы должны проверить это перед усечением

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