2016-08-09 1 views
-1

Я знаю, что это было задано в некоторой степени, но пока я не смог увидеть рабочий пример решения. Я знаю, что для анализа строк HTML существует Html Agility Pack, но я не хочу его загружать/устанавливать. Я получаю содержимое веб-страницы с помощьюC# Regex, чтобы получить строку между двумя строками с подстановочной строкой между ними?

string html = client.DownloadString("http://yoursite.com/page.html"); 

У меня есть метки, которые имеют класс с ними, но некоторые из этих тегов также имеют свой собственный идентификатор, или стиль, и т.д., например:

<td>I Dont want this</td> 
<td class="myClass">I want this</td> 
<td class="myClass" id="myID">I want this</td> 
<td style="border-top-width: 0px; class="myClass">I want this</td> 

Я попытался

<td>(.*?)</td> 

Но она возвращает теги без какого-либо класса, идентификатор и т.д.

Я попытался

<td class="myClass"[^>]*>(.*?)</td> 

Но он возвращает только второй и третий значения <td>, но не четвертый. Как я могу добавить шаблон для возврата <td> с myClass, но игнорирует все, что приходит до или после, как id или style?

+1

Я вынужден указать вам на [этот довольно известный вопрос] (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags) – Jonesopolis

+0

Это часть HTML будет ВСЕГДА иметь тот же формат, который задан вопросом. Не будет никаких ошибок или перегрузок, которые браузеры автозаполняют и автозаменяют. – KingsInnerSoul

+0

Просто добавьте еще один '[^>] *' перед атрибутом 'class'. Если ваш HTML такой же последовательный, как вы говорите, этого должно быть достаточно. –

ответ

0

Это будет определять только атрибут класса или идентификатора, если <td.
Он проходит, если любой из них имеет.

Если вам требуется только значение класса и идентификатор является необязательным, изменить условные
к (?(class)|(?!))

После того, как находит открывающий тег, этот метод просто найти это следующее закрытие.
(Обратите внимание, что он не проверяет открытие <td является самодостаточной тег.
Если это возможно, добавьте (?<!/>) сразу после атомной группы
т (?> ..) (?<!/>))

Класс и значения id находятся в их названных группах захвата.

дословное

@"(?is)<td(?=\s)(?>(?:(?<=\s)class\s*=\s*""(?<class>[^""]*)""|(?<=\s)id\s*=\s*""(?<id>[^""]*)""|"".*?""|'.*?'|[^>]*?)+>)(?(class)|(?(id)|(?!))).*?</td\s*>"

Expanded

(?is) 
< td     # 'td' tag, or any tag for that matter 
(?= \s) 
(?>     # Atomic grouping 
     (?: 
      (?<= \s) 
      class \s* = \s*  # 'class' attribute 
      " 
      (?<class>    # 'class' value              
       [^"]*     
      ) 
      " 
     | (?<= \s) 
      id \s* = \s*   # 'id' attribute 
      " 
      (?<id>     # 'id' value              
       [^"]* 
      ) 
      " 
     | " .*? " 
     | ' .*? ' 
     | [^>]*? 
    )+ 
     > 
) 
(?(class)    # Conditional - Only tags with our 'class' or 'id' attr/value 
    | 
     (?(id) 
     | (?!) 
    ) 
) 
.*? 
</td \s* > 

Btw, на последней строке <td style="border-top-width: 0px; class="myClass">I want this</td>
стиль значение охватывает класс = часть
style="border-top-width: 0px; class="

0

Это должно сделать это: <td(.+|)(class="myClass")(.+|)>(.+)<\/td>

Живой пример: https://regex101.com/r/gG6gH0/2

Но если список любой другой формат, то вы описали, то вы должны исключить символы «<», «>» из группа захвата.

Смежные вопросы