Czy ktoś ma dobry kod C# (i wyrażenia regularne), który będzie parsował ciąg znaków i "łączył" dowolne adresy URL, które mogą znajdować się w ciągu znaków?Kod C# do linki na adresy URL w ciągu znaków
Odpowiedz
Jest to dość proste zadanie można acheive go Regex i gotowy do przejść wyrażenie regularne od:
Coś jak:
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>");
Ty może również zainteresować się nie tylko tworzeniem linków, ale także skracaniem adresów URL. Oto dobry artykuł na ten temat:
Zobacz również:
- Regular Expression Workbench na MSDN
- Converting a URL into a Link in C# Using Regular Expressions
- Regex to find URL within text and make them as link
- Regex.Replace Method na MSDN
- The Problem With URLs przez Jeff Atwood
- Parsing URLs with Regular Expressions and the Regex Object
- Format URLs in string to HTML Links in C#
- Automatically hyperlink URL and Email in ASP.NET Pages with C#
Hi. Świetna odpowiedź. Większość sugestii w twoim poście (i linkach) wydaje się działać, ale wszystkie wydają się łamać wszelkie istniejące linki w ocenianym tekście. –
VSmith możesz wypróbować różne wyrażenia reg z regixlib.com i znaleźć, który z nich działa najlepiej dla Ciebie. –
@VSmith: Sugerujesz, że masz ciąg taki jak "hello there, zobacz: http://www.b.com"; a ty chcesz tylko połączyć drugą? –
To nie jest takie proste, jak można przeczytać w tym blog post by Jeff Atwood. Szczególnie trudno jest wykryć, gdzie kończy się adres URL.
Na przykład, część tylną nawiasie URL czy:
- http : //en.wikipedia.org/wiki/PCTools (CentralPointSoftware)
- URL w nawiasach (http : //en.wikipedia.org) więcej tekstu
W pierwszym przypadku nawiasy są częścią adresu URL. W drugim przypadku nie są!
I jak widać z adresów URL w tej odpowiedzi, nie każdy to robi dobrze :) – Ray
Tak naprawdę, nie chciałem, aby te dwa adresy URL były opatrzone. Ale wygląda na to, że nie jest to obsługiwane. – M4N
Wyrażenie Jeffa wygląda źle w mojej przeglądarce, uważam, że powinno być: "\ (? \ Bhttp: // [-A-Za-z0-9 + & @ # /%? = ~ _() | !: ,.;] * [- A-Za-z0-9 + & @ # /% = ~ _() |] " –
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;
}
Pozdrawiamy za opublikowanie tego :) –
Skończyło się na użyciu czegoś bardzo podobnego, z jedną modyfikacją. W końcu upewniliśmy się, że wymiana nastąpi tylko raz. Oznacza to, że w efekcie stracimy niektóre linki (linki, które występują więcej niż jeden raz), ale usuniemy możliwość zniekształconych linków w dwóch przypadkach: 1) Kiedy są dwa łącza, gdzie jeden jest bardziej szczegółowy niż drugi. np. "http://google.com http://google.com/reader" 2) Kiedy jest mieszanka linków HTML ze zwykłymi linkami tekstowymi. np. "Http://google.com Google" if (input.IndexOf (match.Value) == input.LastIndexOf (match.Value)) { ... } –
dobrze, po wiele badań na ten temat, a kilka prób, aby naprawić razy kiedy
- ludzi wchodzi w http://www.sitename.com i www.sitename.com w tym samym poście
- poprawki do parenthisis podobne (http://www.sitename.com) i http://msdn.microsoft.com/en-us/library/aa752574(vs.85).aspx
- długich adresy, takie jak: 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
używamy teraz rozszerzenia HtmlHelper ...myślałem, że dzielić się i uzyskać wszelkie komentarze:
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;
}
znalazłeś następujące wyrażenia regularnego http://daringfireball.net/2010/07/improved_regex_for_matching_urls
dla mnie wygląda bardzo dobrze. Rozwiązanie Jeffa Atwooda nie obsługuje wielu przypadków. josefresno wydaje mi się, że obsługuję wszystkie przypadki. Ale kiedy próbowałem to zrozumieć (w przypadku jakichkolwiek próśb o wsparcie) mój mózg był gotowany.
Istnieje klasa:
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
}
Użyj go w ten sposób:
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;
}
przypadków testowych:
[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());
}
To działa dobrze, jednak pasuje na takie rzeczy jak o.context lub inny ciąg, który ma w nich okres. Byłoby miło zmusić .com/.org/.net etc, gdzieś w łańcuchu –
Wymusza to również www, co nie zawsze ma miejsce. –
- 1. Zamień adresy URL i @ * na linki
- 2. Java - specjalne adresy URL znaków
- 3. Jak przekierować adresy URL na podstawie ciągu zapytania?
- 4. Zastąp adresy URL w tekście linkami do adresów URL
- 5. Zamień "\\" na "\" w ciągu znaków w C#
- 6. Standardowe adresy URL ExpressJS/kanoniczne adresy URL:
- 7. Uzyskaj adres URL z ciągu znaków
- 8. Rozdzielanie ciągu znaków w C++
- 9. Adresy URL i znaki plus
- 10. JavaScript: wyodrębnij adresy URL z ciągu znaków (w tym querystring) i zwróć tablicę
- 11. Absolutne adresy URL CakePHP
- 12. kod URL w argumencie-c
- 13. C++: podział ciągu znaków na tablicę
- 14. Dynamiczne adresy URL Django
- 15. Wykrywanie kodowania ciągu znaków w C/C++
- 16. PHP - Dodaj link do adresu URL w ciągu znaków
- 17. Adresy URL bezpieczne identyfikatory UUID w najmniejszej liczbie znaków
- 18. C# zawiera część ciągu znaków
- 19. Wykryj adresy URL w UILabel
- 20. łączy względne adresy URL?
- 21. Przekazywanie ciągu znaków do kodu C w systemie Android NDK
- 22. C# - kod do zamówienia przez właściwość używającą nazwy właściwości w postaci ciągu znaków
- 23. Zamień wiele znaków w ciągu znaków w Objective-C?
- 24. Kopiowanie ciągu znaków z argv do tablicy char w C
- 25. format ciągu znaków w języku C#
- 26. Funkcja usuwania spacji z ciągu znaków/znaków w C
- 27. Wysyłanie ciągu znaków przez UDP w C++
- 28. Odwrotność wszystkich znaków alfabetu w ciągu C#
- 29. Znajdź tekst w ciągu znaków z C#
- 30. C# trzeci indeks znaku w ciągu znaków
To wydaje się być pytanie z oparty wyrażenie-Kanoniczne regularne rozwiązanie. Być może ktoś mógłby edytować tytuł, aby pomóc go znaleźć? – JasonSmith