Как разделить текст с помощью регулярных выражений, но разделенные слова продолжают сохранять разделитель регулярных выражений?

У меня есть текст, и я использую это простое регулярное выражение, чтобы разделить его на слова: [ \n]. Он разбивает текст на слова, используя пробелы и разрывы строк.

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

Я использую метод String#split.


person Renato Dinhani    schedule 17.08.2011    source источник
comment
Ваш \n означает что-то особенное (конец предложения)? Вы не обрабатываете обычные абзацы в несколько строк с помощью . как конец предложения?   -  person toto2    schedule 17.08.2011
comment
@toto2 Пунктуация также используется для определения конца предложения, но содержимое исходит из содержимого HTML, поэтому во многих предложениях, таких как заголовок, нет знаков препинания, определяющих, где заканчиваются предложения, а только разрыв строки.   -  person Renato Dinhani    schedule 17.08.2011
comment
Я не уверен, что вы должны полагаться на \n при обработке HTML, так как у вас может быть прекрасный документ без единого \n.   -  person toto2    schedule 17.08.2011
comment
@toto2 toto2 Текст, который я обрабатываю, поступает из API Boilerpipe (внешний процессор HTML) и содержит разрывы строк в соответствии с содержимым HTML.   -  person Renato Dinhani    schedule 17.08.2011


Ответы (5)


Вы можете использовать lookbehind, как предложил @Piotr Findeisen (+1):

public class RegexExample{
    public static void main(String[] args) {
    String s = "firstWordWithSpaceAfter secondWordWithSpaceAfter wordWithLineBreakAfter\nlastWord";
    String sa[] = s.split("(?<=[ \\n])");
    for (String saa : sa )
        System.out.println("[" + saa + "]");
    }
}

Выход:

[firstWordWithSpaceAfter ]
[secondWordWithSpaceAfter ]
[wordWithLineBreakAfter
]
[lastWord]

Краткое объяснение:

?<= заглядывает назад, что означает, что вы получили совпадение, если данные перед искомым выражением равны регулярному выражению, идущему после ?<= (в данном случае [ \\n])

[ \\n] – это регулярное выражение, означающее один из символов в []

поэтому все регулярное выражение говорит о разделении каждый раз, когда символ перед выражением/словом является либо пробелом, либо \n.

Поскольку мы не пытались сопоставить пробел или \n, они не будут удалены.

person MByD    schedule 17.08.2011
comment
@Renato Dinhani Conceição - я не эксперт по регулярным выражениям, но надеюсь, что его редактирование достаточно понятно. - person MByD; 17.08.2011
comment
Вы помещаете свое регулярное выражение в круглые скобки. Это необходимо? - person Renato Dinhani; 17.08.2011
comment
Да, забыл упомянуть, это часть ретроспективы. - person MByD; 17.08.2011
comment
Спасибо за ответ и объяснение. Работал! :D - person Renato Dinhani; 17.08.2011

Рассмотрите возможность использования положительного просмотра назад/упреждения нулевой ширины. См. шаблон javadoc в < em>Специальные конструкции (без захвата)

person Piotr Findeisen    schedule 17.08.2011

Я думаю, что ваш единственный вариант - сделать что-то вроде этого:

String myString = "Joe Blow\n1234 Fake Road\nHere, There, 12345";
String[] lines = myString.split("\\n");
Set<String[]> wordsByLine = new LinkedHashSet<String[]>();
for (String line : lines) {
  wordsByline.add(line.split(" "));
}
person josh.trow    schedule 17.08.2011

Очень быстро пришло мне в голову, если бы регулярное выражение всегда соответствовало одиночным символам, вы могли бы использовать длину, чтобы определить, где они находились в исходной строке. Затем вы можете взять подстроку для символа-разделителя.

Немного грязно, но должно сработать.

person Tom Elliott    schedule 17.08.2011

Я все еще не уверен, что вы пытаетесь сделать, но если \n имеет значение, отличное от " ", вы должны иметь дело с ними отдельно.

String[] sentences = text.split("\\n");
...
for (String sentence : sentences) {
    ...
    String[] words = sentence.split(" ");
    ...
}
person toto2    schedule 17.08.2011