Попытка извлечь образец в строке - PullRequest
1 голос
/ 05 июня 2010

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

Вот мой код:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ParseText1 {

public static void main(String[] args) {

    String content = "<p>Yada yada yada <code> foo ddd</code>yada yada ...\n"
        + "more here <2004-08-24> bar<Bob Joe> etc etc\n"
        + "more here again <2004-09-24> bar<Bob Joe> <Fred Kej> etc etc\n"
        + "more here again <2004-08-24> bar<Bob Joe><Fred Kej> etc etc\n"
        + "and still more <2004-08-21><2004-08-21> baz <John Doe> and now <code>the end</code> </p>\n";

    Pattern p = Pattern
    .compile("<[1234567890]{4}-[1234567890]{2}-[1234567890]{2}>.*?<[^%0-9/]*>",
            Pattern.MULTILINE);

    Matcher m = p.matcher(content);

    // print all the matches that we find
    while (m.find()) {

        System.out.println(m.group());

    }

}
}

Вывод, который я получаю:

<2004-08-24> bar<Bob Joe>
<2004-09-24> bar<Bob Joe> <Fred Kej>
<2004-08-24> bar<Bob Joe><Fred Kej>
<2004-08-21><2004-08-21> baz <John Doe> and now <code>

Вывод, который я хочу получить:

<2004-08-24> bar<Bob Joe>
<2004-08-24> bar<Bob Joe>
<2004-08-24> bar<Bob Joe>
<2004-08-21> baz <John Doe>

Короче говоря, последовательность «дата», «текст (или пробел)» и «имя» должна быть извлечена. Всего остального следует избегать. Например, у тега «Fred Kej» не было никакого тега «date» перед ним, поэтому он должен быть помечен как недействительный.

Также, как дополнительный вопрос, есть ли способ сохранить или отследить фрагменты текста, которые были пропущены / отклонены, как и действительные тексты.

Спасибо, Брайан

Ответы [ 3 ]

3 голосов
/ 05 июня 2010

Этот шаблон работает: "<\\d{4}-\\d{2}-\\d{2}>[^<]*<[^%\\d>]*>"

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


String content = "<p>Yada yada yada <code> foo ddd</code>yada yada ...\n"
    + "more here <2004-08-24> bar<Bob Joe> etc etc\n"
    + "more here again <2004-09-24> bar<Bob Joe> <Fred Kej> etc etc\n"
    + "more here again <2004-08-24> bar<Bob Joe><Fred Kej> etc etc\n"
    + "and still more <2004-08-21><2004-08-21> baz <John Doe> and now <code>the end</code> </p>\n";

Pattern p = Pattern.compile(
    "<\\d{4}-\\d{2}-\\d{2}>[^<]*<[^%\\d>]*>",
    Pattern.MULTILINE
);

Matcher m = p.matcher(content);
int index = 0;
while (m.find()) {
    System.out.println(content.substring(index, m.start()));
    System.out.println("**MATCH START**" + m.group() + "**MATCH END**");
    index = m.end();
}
System.out.println(content.substring(index));

Это печатает:

<p>Yada yada yada <code> foo ddd</code>yada yada ...
more here 
**MATCH START**<2004-08-24> bar<Bob Joe>**MATCH END**
 etc etc
more here again 
**MATCH START**<2004-09-24> bar<Bob Joe>**MATCH END**
 <Fred Kej> etc etc
more here again 
**MATCH START**<2004-08-24> bar<Bob Joe>**MATCH END**
<Fred Kej> etc etc
and still more <2004-08-21>
**MATCH START**<2004-08-21> baz <John Doe>**MATCH END**
 and now <code>the end</code> </p>
0 голосов
/ 05 июня 2010

Используйте это регулярное выражение вместо. Также добавлен код для отображения отброшенных фрагментов текста.

    Pattern p = Pattern.compile(
            "(<[0-9]{4}-[0-9]{2}-[0-9]{2}>)" + // <2004-08-21>
            "([^<]*)" +                        //  baz
            "(<[^%0-9>]*>)",                   // <John Doe>
            Pattern.MULTILINE);

    Matcher m = p.matcher(content);

    // print all the matches that we find
    int start = 0;
    while (m.find()) {
        System.out.println("\t"
                + content.substring(start, m.end()).replaceAll("\n", "\n\t"));
        System.out.println(m.group());
        start = m.end();
    }
    System.out.println("\t"
                + content.substring(start).replaceAll("\n", "\n\t"));

Выход

        <p>Yada yada yada <code> foo ddd</code>yada yada ...
        more here <2004-08-24> bar<Bob Joe>
<2004-08-24> bar<Bob Joe>
         etc etc
        more here again <2004-09-24> bar<Bob Joe>
<2004-09-24> bar<Bob Joe>
         <Fred Kej> etc etc
        more here again <2004-08-24> bar<Bob Joe>
<2004-08-24> bar<Bob Joe>
        <Fred Kej> etc etc
        and still more <2004-08-21><2004-08-21> baz <John Doe>
<2004-08-21> baz <John Doe>
         and now <code>the end</code> </p>

Где строки с отступом соответствуют отброшенным фрагментам

0 голосов
/ 05 июня 2010

Вы пытались добавить символ > в список вещей, не разрешенных во втором наборе скобок?

Pattern p = Pattern
    .compile("<[1234567890]{4}-[1234567890]{2}-[1234567890]{2}>.*?<[^%0-9/>]*>",
            Pattern.MULTILINE);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...