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
- la gente ingresa en http://www.sitename.com y www.sitename.com en la misma publicación
- correcciones para paréntesis como ( http://www.sitename.com ) y http://msdn.microsoft.com/en-us/library/aa752574(vs.85).aspx
- 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/-/._/?/,/'////+&%/$#/=~])*$",
"<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 :
- Regular Expression Workbench en MSDN
- Convertir una URL en un enlace en C # usando expresiones regulares
- Regex para encontrar la URL dentro del texto y hacerlos como enlace
- Regex en MSDN
- El problema con las URL por Jeff Atwood
- Análisis de URL con expresiones regulares y el objeto Regex
- Formato de URL en cadena a enlaces HTML en C #
- Hipervínculo automático de URL y correo electrónico en páginas ASP.NET con C #
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!
Se han encontrado después de la expresión regular http://daringfireball.net/2010/07/improved_regex_for_matching_urls
para mi se ve muy bien La solución de Jeff Atwood no maneja muchos casos. josefresno me parece manejar todos los casos. Pero cuando he tratado de entenderlo (en caso de cualquier solicitud de apoyo), mi cerebro fue hervido.
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( " ", " " );
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;
}