remarks para google generate example c# asp.net regex linkify

google - Código C#para enlazar urls en una cadena



para c# (6)

Bueno, después de una gran cantidad de investigación sobre esto, y varios intentos de arreglar los tiempos cuando

  1. la gente ingresa en http://www.sitename.com y www.sitename.com en la misma publicación
  2. correcciones para paréntesis como ( http://www.sitename.com ) y http://msdn.microsoft.com/en-us/library/aa752574(vs.85).aspx
  3. largas urls como: http://www.amazon.com/gp/product/b000ads62g/ref=s9_simz_gw_s3_p74_t1?pf_rd_m=atvpdkikx0der&pf_rd_s=center-2&pf_rd_r=04eezfszazqzs8xfm9yd&pf_rd_t=101&pf_rd_p=470938631&pf_rd_i=507846

ahora estamos usando esta extensión HtmlHelper ... pensé que compartiría y obtendría cualquier comentario:

private static Regex regExHttpLinks = new Regex(@"(?<=/()/b(https?://|www/.)[-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|](?=/))|(?<=(?<wrap>[=~|_#]))/b(https?://|www/.)[-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|](?=/k<wrap>)|/b(https?://|www/.)[-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|]", RegexOptions.Compiled | RegexOptions.IgnoreCase); public static string Format(this HtmlHelper htmlHelper, string html) { if (string.IsNullOrEmpty(html)) { return html; } html = htmlHelper.Encode(html); html = html.Replace(Environment.NewLine, "<br />"); // replace periods on numeric values that appear to be valid domain names var periodReplacement = "[[[replace:period]]]"; html = Regex.Replace(html, @"(?<=/d)/.(?=/d)", periodReplacement); // create links for matches var linkMatches = regExHttpLinks.Matches(html); for (int i = 0; i < linkMatches.Count; i++) { var temp = linkMatches[i].ToString(); if (!temp.Contains("://")) { temp = "http://" + temp; } html = html.Replace(linkMatches[i].ToString(), String.Format("<a href=/"{0}/" title=/"{0}/">{1}</a>", temp.Replace(".", periodReplacement).ToLower(), linkMatches[i].ToString().Replace(".", periodReplacement))); } // Clear out period replacement html = html.Replace(periodReplacement, "."); return html; }

¿Alguien tiene algún código c # bueno (y expresiones regulares) que analice una cadena y "vincule" cualquier URL que pueda estar en la cadena?


Es una tarea bastante simple que puede lograr con Regex y una expresión regular lista para Regex desde:

Algo como:

var html = Regex.Replace(html, @"^(http|https|ftp)/://[a-zA-Z0-9/-/.]+" + "/.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?" + "([a-zA-Z0-9/-/._/?/,/'////+&amp;%/$#/=~])*$", "<a href=/"$1/">$1</a>");

También puede interesarle no solo crear enlaces, sino también acortar las URL. Aquí hay un buen artículo sobre este tema:

Ver también :


Hay clase

public class TextLink { #region Properties public const string BeginPattern = "((http|https)://)?(www.)?"; public const string MiddlePattern = @"([a-z0-9/-]*/.)+[a-z]+(:[0-9]+)?"; public const string EndPattern = @"(//S*)?"; public static string Pattern { get { return BeginPattern + MiddlePattern + EndPattern; } } public static string ExactPattern { get { return string.Format("^{0}$", Pattern); } } public string OriginalInput { get; private set; } public bool Valid { get; private set; } private bool _isHttps; private string _readyLink; #endregion #region Constructor public TextLink(string input) { this.OriginalInput = input; var text = Regex.Replace(input, @"(^/s)|(/s$)", "", RegexOptions.IgnoreCase); Valid = Regex.IsMatch(text, ExactPattern); if (Valid) { _isHttps = Regex.IsMatch(text, "^https:", RegexOptions.IgnoreCase); // clear begin: _readyLink = Regex.Replace(text, BeginPattern, "", RegexOptions.IgnoreCase); // HTTPS if (_isHttps) { _readyLink = "https://www." + _readyLink; } // Default else { _readyLink = "http://www." + _readyLink; } } } #endregion #region Methods public override string ToString() { return _readyLink; } #endregion }

Úsalo en este método:

public static string ReplaceUrls(string input) { var result = Regex.Replace(input.ToSafeString(), TextLink.Pattern, match => { var textLink = new TextLink(match.Value); return textLink.Valid ? string.Format("<a href=/"{0}/" target=/"_blank/">{1}</a>", textLink, textLink.OriginalInput) : textLink.OriginalInput; }); return result; }

Casos de prueba:

[TestMethod] public void RegexUtil_TextLink_Parsing() { Assert.IsTrue(new TextLink("smthing.com").Valid); Assert.IsTrue(new TextLink("www.smthing.com/").Valid); Assert.IsTrue(new TextLink("http://smthing.com").Valid); Assert.IsTrue(new TextLink("http://www.smthing.com").Valid); Assert.IsTrue(new TextLink("http://www.smthing.com/").Valid); Assert.IsTrue(new TextLink("http://www.smthing.com/publisher").Valid); // port Assert.IsTrue(new TextLink("http://www.smthing.com:80").Valid); Assert.IsTrue(new TextLink("http://www.smthing.com:80/").Valid); // https Assert.IsTrue(new TextLink("https://smthing.com").Valid); Assert.IsFalse(new TextLink("").Valid); Assert.IsFalse(new TextLink("smthing.com.").Valid); Assert.IsFalse(new TextLink("smthing.com-").Valid); } [TestMethod] public void RegexUtil_TextLink_ToString() { // default Assert.AreEqual("http://www.smthing.com", new TextLink("smthing.com").ToString()); Assert.AreEqual("http://www.smthing.com", new TextLink("http://www.smthing.com").ToString()); Assert.AreEqual("http://www.smthing.com/", new TextLink("smthing.com/").ToString()); Assert.AreEqual("https://www.smthing.com", new TextLink("https://www.smthing.com").ToString()); }


No es tan fácil como puedes leer en esta publicación de blog de Jeff Atwood . Es especialmente difícil detectar dónde termina una URL.

Por ejemplo, si el paréntesis final es parte de la URL o no:

  • http: //en.wikipedia.org/wiki/PCTools (CentralPointSoftware)
  • una URL entre paréntesis (http: //en.wikipedia.org) más texto

En el primer caso, los paréntesis son parte de la URL. En el segundo caso no lo son!



protected string Linkify( string SearchText ) { // this will find links like: // http://www.mysite.com // as well as any links with other characters directly in front of it like: // href="http://www.mysite.com" // you can then use your own logic to determine which links to linkify Regex regx = new Regex( @"/b(((/S+)?)(@|mailto/:|(news|(ht|f)tp(s?))/://)/S+)/b", RegexOptions.IgnoreCase ); SearchText = SearchText.Replace( "&nbsp;", " " ); MatchCollection matches = regx.Matches( SearchText ); foreach ( Match match in matches ) { if ( match.Value.StartsWith( "http" ) ) { // if it starts with anything else then dont linkify -- may already be linked! SearchText = SearchText.Replace( match.Value, "<a href=''" + match.Value + "''>" + match.Value + "</a>" ); } } return SearchText; }