Замените гиперссылки на обычный текст, за которым следует URL в скобках, используя C # - PullRequest
0 голосов
/ 29 февраля 2012

Как бы заменить все теги href в строке, такие как:

Заголовок ссылки и Другая ссылка

.. с URL-адресом, заключенным в скобки после содержимого тега:

заголовок ссылки [http: // thedomain.com/about] и другая ссылка [http://anotherlink.com]

Разрешить для капитала HREF и капитала /A.

Это будет использоваться для переформатирования гиперссылок при отправке текстового электронного письма.

Может использоваться RegEx. Похожий на: Замена гиперссылки на обычный текстовый URL с использованием REGEX

Ответы [ 3 ]

4 голосов
/ 01 марта 2012

Это регулярное выражение C # и регулярное выражение замены работало для меня в моем тестировании с использованием Expresso . Параметры регулярного выражения задают нечувствительность к регистру, как вы и просили, а также игнорировать пробелы, которые я хотел бы оставить для удобства чтения.

using System;
using System.Text.RegularExpressions;

string inputText = "your text here";
string rx = "<a\\s+ .*? href\\s*=\\s*(?:\"|') (?<url>.*?) (?:\"|') .*?> (?<anchorText>.*?) \\</a>";
Regex regex = new Regex( rx, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace );
string regexReplace = "${anchorText} [${url}]";

string result = regex.Replace( inputText, regexReplace );
1 голос
/ 29 февраля 2012

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

Лучше было бы использовать вместо этого анализатор, например http://roberto.open -lab.com / 2010/03/04 / a-html-sanitizer-for-c /

Также смотрите ответы здесь: RegEx соответствует открытым тегам, за исключением автономных тегов XHTML

Редактировать

Хорошо, здесь есть 1 способ использования htmlAgilityPack :

static void Main(string[] args)
    {
        HtmlDocument htmlDoc = new HtmlDocument();    
        htmlDoc.Load(@"c:\test.html");    
        var listofHyperLinkTags = from hyperlinks in htmlDoc.DocumentNode.Descendants()
                          where hyperlinks.Name == "a" &&
                               hyperlinks.Attributes["href"] != null
                          select new
                          {
                              Address = hyperlinks.Attributes["href"].Value,
                              LinkTitle = hyperlinks.InnerText
                          };

        foreach(var linkDetail in listofHyperLinkTags)
            Console.WriteLine(linkDetail.LinkTitle + "[" + linkDetail.Address + "]");

        Console.Read();
    }

Если LINQ не поддерживается, используйте выражение XPath

var anchorTags = htmlDoc.DocumentNode.SelectNodes("//a");

foreach (var tag in anchorTags)
{
}

Если вы хотитечтобы изменить документ, используйте что-то вроде (могут быть и лучшие способы)

var parentNode = tag.ParentNode;

HtmlNode node = htmlDoc.CreateElement("br");

node.InnerHtml = tag.InnerText + "[" + tag.Attributes["href"].Value + "]";
parentNode.RemoveChild(tag);
parentNode.AppendChild(node); 
1 голос
/ 29 февраля 2012

Полная замена

После некоторого затягивания с этим я выкладываю это решение. Используйте это или нет, это больше для моей текущей или будущей ссылки. Удивительно, но только часть tag-att-val покрывает почти все варианты использования. Тем не менее, регулярное выражение не рекомендуется для анализа HTML. Но если он используется, он должен быть достаточно точным.

Пример кода на C # можно найти здесь - http://ideone.com/TBxXm
Он был отлажен в VS2008 с использованием исходной страницы с CNN.com, затем рабочая копия вставлена ​​в ideone для постоянной ссылки.

Вот легкомысленное регулярное выражение

<a 
  (?=\s) 

  # Optional preliminary att-vals (should prevent overruns)
  (?:[^>"']|"[^"]*"|'[^']*')*?

  # HREF, the attribute we're looking for
  (?<=\s) href \s* =

     # Quoted attr value (only)
     # (?> \s* (['"]) (.*?) \1 )
     # ---------------------------------------
     # Or,
     # Unquoted attr value (only)
     # (?> (?!\s*['"]) \s* ([^\s>]*) (?=\s|>) )
     # ---------------------------------------
     # Or,

  # Quoted/unquoted attr value (empty-unquoted value is allowed)
  (?: (?>             \s* (['"]) (?<URL>.*?)     \1       )
    | (?> (?!\s*['"]) \s*        (?<URL>[^\s>]*) (?=\s|>) )   
  )

  # Optional remaining att-vals
  (?> (?:".*?"|'.*?'|[^>]?)+ )

  # Non-terminated tag
  (?<!/)
>
(?<TEXT>.*?)
</a \s*>

и здесь, как он существует в источнике C #

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = @"
               <a asdf = href=  >BLANK</a>
               <a href= a""'tz target=_self >ATZ</a>
               <a href=/2012/02/26/world/meast/iraq-missing-soldier-id/index.html?hpt=hp_bn1 target=""_self"">Last missing U.S. soldier in Iraq ID'd</a>
               <a id=""weatherLocBtn"" href=""javascript:MainLocalObj.Weather.checkInput('weather',document.localAllLookupForm.inputField.value);""><span>Go</span></a>
               <a href=""javascript:CNN_handleOverlay('profile_signin_overlay')"">Log in</a>
               <a no='href' here> NOT FOUND </a>
               <a this href= is_ok > OK </a>
            ";
            string regex = @"
               <a 
                 (?=\s) 
                 (?:[^>""']|""[^""]*""|'[^']*')*?
                 (?<=\s) href \s* =
                 (?: (?>              \s* (['""]) (?<URL>.*?)     \1       )
                   | (?> (?!\s*['""]) \s*         (?<URL>[^\s>]*) (?=\s|>) )   
                 )
                 (?> (?:"".*?""|'.*?'|[^>]?)+ )
                 (?<!/)
               >
               (?<TEXT>.*?)
               </a \s*>
            ";
            string output = Regex.Replace(input, regex, "${TEXT} [${URL}]",
                                RegexOptions.IgnoreCase |
                                RegexOptions.Singleline |
                                RegexOptions.IgnorePatternWhitespace);

            Console.WriteLine(input+"\n------------\n");
            Console.WriteLine(output);
        }
    }
}

с выводом

           <a asdf = href=  >BLANK</a>
           <a href= a"'tz target=_self >ATZ</a>
           <a href=/2012/02/26/world/meast/iraq-missing-soldier-id/index.html?hpt=hp_bn1 target="_self">Last missing U.S. soldier in Iraq ID'd</a>
           <a id="weatherLocBtn" href="javascript:MainLocalObj.Weather.checkInput('weather',document.localAllLookupForm.inputField.value);"><span>Go</span></a>
           <a href="javascript:CNN_handleOverlay('profile_signin_overlay')">Log in</a>
           <a no='href' here> NOT FOUND </a>
           <a this href= is_ok > OK </a>

------------

           BLANK []
           ATZ [a"'tz]
           Last missing U.S. soldier in Iraq ID'd [/2012/02/26/world/meast/iraq-missing-soldier-id/index.html?hpt=hp_bn1]
           <span>Go</span> [javascript:MainLocalObj.Weather.checkInput('weather',document.localAllLookupForm.inputField.value);]
           Log in [javascript:CNN_handleOverlay('profile_signin_overlay')]
           <a no='href' here> NOT FOUND </a>
            OK  [is_ok]

Ура!

...