0

Доброго времени суток. Необходимо выдрать текст к примеру между тегами с помощью регулярных выражений.

static void Main(string[] args)
    {
        string text = @"bla bla bla blablaa <title>TITLE</title> bla bla bla bla";
    string match = Regex.Match(text, @"&lt;title&gt;(.*)&lt;/title&gt;").ToString();

    Console.WriteLine(match);
}

В нескольких местах в нете нашел, что именно такой паттерн должен выдрать текст между тегами, но на практике в строке match оказывается значение "<title>TITLE</title>", а мне нужно, чтобы там было только "TITLE". Что я сделал не так?

  • 2
    Вы случайно не собираетесь парсить HTML регулярными выражениями? Подумайте о том, что может быть в комментарии. – VladD Feb 02 '13 at 17:30
  • Ну теги это я как пример привел просто. А вообще, если скажем нужно спарсить просто тот же тайтл, то зачем для такого простого действия подключать еще какие-то сторонние библиотеки типа HtmlAgilityPack, ведь в дотнете на сколько мне известно нет встроенных средств для парсинга HTML. Еще можно в принципе сделать метод для выдергивания текста из тегов с помощью встроенных методов string.StartsWith, string.EndsWith и т. д. Но это получится строк 8 кода против одной строки регуляркой. Да и думается мне, что регулярки побыстрее будут работать, или нет? Я нуб, так что критика приветствуется ) – junior_dev Feb 02 '13 at 17:54
  • 1
    @junior_dev: давайте я повторюсь. Внутри HTML-файла позволяются комментарии. Ответьте себе на вопрос: что может быть в комментарии? Если ответ "например, любой HTML-тег", вы на правильном пути. – VladD Feb 02 '13 at 18:18
  • 1
    @junior_dev: регулярки будут работать не быстрее, чем ручной парсинг. Но зато они проще. И при ручном парсинге вы судя по всему собираетесь сделать точно такую же ошибку. – VladD Feb 02 '13 at 18:20
  • @VladD Понятно, значит нужно первым делом удалить все комментарии из HTML строки, если они есть. Сделать это проще всего теми же регулярками, верно? А потом уже со строкой, очищенной от комментариев, делать что угодно. И еще, перед тем как работать со строкой, нужно удостовериться, что там кодировка UTF-8, а то на некоторых сайтах еще может быть windows-1251, нужно перекодировать, иначе регулярки нормально не будут работать. – junior_dev Feb 02 '13 at 18:42
  • 1
    @junior_dev: Не-а, этого недостаточно. Кроме комментариев (которые ещё надо уметь выкусить) есть блоки CDATA и различные варианты расстановки пробелов. Есть ещё entities. Ещё строки внутри скриптов. Вы и правда собираетесь обойти все эти препятствия? Если да, мои поздравления, вы собираетесь написать ещё одну библиотеку для парсинга HTML. Может, лучше взять готовую? – VladD Feb 02 '13 at 18:55
  • @VladD Ясно, спасибо за разъяснение. Кстати, а вы не могли бы посоветовать какой-нить парсер, кроме HtmlAgilityPack? Нет, он очень даже ок, но хотелось бы и другие посмотреть, а все только про него и пишут. Неужели альтернатив нет? – junior_dev Feb 02 '13 at 19:16
  • (Это не ответ, но комментарии сверху закончились, так что продолжаю тут.)

    Я другого парсера не знаю, сорри, посоветовать не могу. Но на StackOverflow предлагают и другие варианты:

    Хотя HtmlAgilityPack, конечно, в лидерах.

    – VladD Feb 02 '13 at 20:28

2 Answers2

8

Нужно исключить из результата теги (Positive lookbehind/lookahead):

(?<=<title>)(.*)(?=</title>)
Deleted
  • 371
nitrocaster
  • 4,492
1

Вообще проблема в твоём коде была из-за того что Regex.Match возвращает совпадение с шаблоном регулярного выражения, тоесть с "<title>(.*)</title>", часть регулярного выражения "(.*)" называется "группой". Поэтому у класса Match есть свойство Groups, из которого по индексу группы или по её имени (имя задаётся к примеру так: (?<title>.*) можно выковырять нужную группу.

А вообще за парсинг XHTML'а регулярками действительно нужно бить по-рукам.

devheart
  • 66
  • 8