Простое сопоставление строк с использованием Regex - PullRequest
0 голосов
/ 18 марта 2011

У меня есть этот поток строк:

"do=whoposted&amp;t=1934067" rel=nofollow>61</A></TD><TD class=alt2 align=middle>5,286</TD></TR><TR><TD id=td_threadstatusicon_1911046 class=alt1><IMG id=thread_statusicon_1911046 border=0 alt="" src="http://url.com/forum/images/statusicon/thread_new.gif"> </TD><TD class=alt2><IMG title=Node border=0 alt=Node src="http://url.com/forum/images/icons/new.png"></TD><TD id=td_threadtitle_1911046 class=alt1 title="http://lulzimg.com/i14/7bd11b.jpg &#10; &#10;Complete name : cool-thread...."><DIV><A id=thread_gotonew_1911046 href="http://url.com/forum/f80/cool-topic-new/"><IMG class=inlineimg title="Go to first new post" border=0 alt="Go to first new post" src="http://url.com/forum/images/buttons/firstnew.gif"></A> [MULTI] <A style="FONT-WEIGHT: bold" id=thread_title_1911046 href="http://url.com/forum/f80/cool-topic-name-1911046/">Cool Topic Name</A> </DIV><DIV class=smallfont><SPAN style="CURSOR: pointer" onclick="window.open('http://url.com/forum/members/u2031889/', '_self')">m3no</SPAN> </DIV></TD><TD class=alt2 title="Replies: 11, Views: 1,554"><DIV style="TEXT-ALIGN: right; WHITE-SPACE: nowrap" class=smallfont>Today <SPAN class=time>08:04 AM</SPAN><BR>by <A href="http://url.com/forum/members/u1131830/" rel=nofollow>karetsos</A> <A "

Интересующие меня строки похожи на это:

<A style="FONT-WEIGHT: bold" id=thread_title_1911046 href="http://url.com/forum/f80/cool-topic-name-1911046/">Cool Topic Name</A>

Отсюда все, что я пытаюсь извлечь, это:

Thread id: 1911046 (could be from either location in the string)
Thread name: "Cool Topic Name"
Thread link: "http://url.com/forum/f80/cool-topic-name-1911046/"

В настоящее время я использую это:

Regex pattern = new Regex ( "<A\\s+href=\"([^\"]*)\">([^\\x00]*?)\\s+id=thread_title_(\\S+)</A>" );

MatchCollection matches = pattern.Matches ( doc.ToString ( ) );

foreach ( Match match in matches )
{
    int id = Convert.ToInt32 ( match.Groups [ 1 ].Value );

    string name = match.Groups [ 3 ].Value;
    string link = match.Groups [ 2 ].Value;

    ...
}

Буду признателен, если кто-нибудь поможет мне исправить шаблон, чтобы он соответствовал ему. Раньше это работало, но возвращает 0 совпадений.

Ответы [ 4 ]

3 голосов
/ 18 марта 2011

Майкл Папиле ответ работает. Удалите косую черту (/) из начала и конца шаблона, который вы показали в своем последнем комментарии. Прямая косая черта - это разделитель шаблонов в Ruby - мы не используем их в .NET:

var rg = new Regex(@"<A(?:[^<]*)thread_title_(\d+) href=""([^""]*)"">([^<]*)");

дословной строке (@"...") вам нужно только избегать двойных кавычек, удваивая их.

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

Редактировать (снова): Вы правы, этот шаблон не работает на реальной странице. Из трех ответов только Ridgrunner возвращает 24 совпадения.

2 голосов
/ 18 марта 2011

Если предположить, что будет любое количество атрибутов, а атрибут href всегда идет после id, а атрибуты могут иметь или не иметь свои значения в кавычках, то этот должен выполнить трюк:

Regex pattern = new Regex(
    @"<A\b             # Begin start tag
    [^>]+?             # Lazily consume up to id attribute
    id\s*=\s*['""]?thread_title_([^>\s'""]+)['""]?  # $1: id
    [^>]+?             # Lazily consume up to href attribute
    href\s*=\s*['""]?([^>\s'""]+)['""]?             # $2: href
    [^>]*              # Consume up to end of open tag
    >                  # End start tag
    (.*?)                                           # $3: name
    </A\s*>            # Closing tag", 
    RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);

Редактировать: Исправлено выражение, которое занимало конечную часть начального тега. (Было [^>]+)

1 голос
/ 20 марта 2011

Это должно сделать это ...

<a[^>]+thread_title_(?<id>\d+)[^>]+href="(?<link>[^"]*)">(?<name>[^<]*)</a>

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

Еще одна вещь, на которую следует обратить внимание, это нотация (?<link>, которая является именованной группой.Это совпадает с обычной группой.Но затем вы можете получить доступ к этим группам в C # по их имени или по индексу.

Вы можете увидеть это в действии здесь ...

http://regexhero.net/tester/?id=7855af6f-7774-4a7c-afa2-81c3e24cf496

ПоКстати, используйте кнопку .NET в верхней части Regex Hero для генерации C #, и тогда кавычки будут правильно экранированы для вас.

1 голос
/ 18 марта 2011

Я не программирую на c #, но здесь есть регулярное выражение, которое работает в ruby ​​(наверное, у вас, ребята, есть \\ для обозначения классов символов?)

/<A.*thread_title_(\d+) href=\"([^\"]*)\">([^<]*)/   

EDIT Попробуй это: thread_title_(\d+) href=\"([^\"]*)\"\>(.*?)<\/A> это соответствует 2 из них в том, что ты сделал. Если вам нужно сопоставлять сложные вещи в HTML, регулярные выражения не годятся, вы должны использовать синтаксический анализатор XML / HTML

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