Köşeli parantez dahil tüm HTML etiketlerini değiştirmek / kaldırmak için C # normal ifadesini nasıl kullanabilirim? Birisi bana kod konusunda yardımcı olabilir mi?
Köşeli parantez dahil tüm HTML etiketlerini değiştirmek / kaldırmak için C # normal ifadesini nasıl kullanabilirim? Birisi bana kod konusunda yardımcı olabilir mi?
Yanıtlar:
Daha önce de belirtildiği gibi, XML veya HTML belgelerini işlemek için normal ifadeler kullanmamalısınız. İç içe geçmiş yapıları genel bir şekilde ifade etmenin bir yolu olmadığından, HTML ve XML belgeleriyle çok iyi performans göstermezler.
Aşağıdakileri kullanabilirsiniz.
String result = Regex.Replace(htmlDocument, @"<[^>]*>", String.Empty);
Bu çoğu durumda işe yarar, ancak bunun beklendiği gibi çalışmadığı durumlar (örneğin, CDATA içeren köşeli parantezler) olacaktır.
Doğru cevap bunu yapmayın, HTML Çeviklik Paketi'ni kullanın .
Eklemek için düzenlendi:
Jesse tarafından aşağıdaki yorumdan utanmadan çalmak ve tüm bunlardan sonra soruyu yetersiz cevaplamakla suçlanmaktan kaçınmak için, HTML Çeviklik Paketi'ni kullanarak en kusurlu şekilde oluşturulmuş, kaprisli HTML parçalarıyla bile çalışan basit, güvenilir bir snippet:
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(Properties.Resources.HtmlContents);
var text = doc.DocumentNode.SelectNodes("//body//text()").Select(node => node.InnerText);
StringBuilder output = new StringBuilder();
foreach (string line in text)
{
output.AppendLine(line);
}
string textOnly = HttpUtility.HtmlDecode(output.ToString());
HTML'yi ayrıştırmak için normal bir ifade kullanmak için çok az savunulabilir durum vardır, çünkü HTML geleneksel olmayan bir normal ifade motorunda bile sağlamak çok acı verici bir bağlam farkındalığı olmadan doğru şekilde ayrıştırılamaz. RegEx ile orada kısmen yol alabilirsiniz, ancak manuel doğrulama yapmanız gerekir.
Html Agility Pack, HTML'ye içeriksiz bir dilbilgisi olarak naif davranmanın yol açabileceği sapmaları manuel olarak düzeltme ihtiyacını azaltacak sağlam bir çözüm sağlayabilir.
Düzenli bir ifade size çoğunlukla istediğinizi sağlayabilir, ancak çok yaygın durumlarda başarısız olur. HTML Agility Pack'den daha iyi / daha hızlı bir ayrıştırıcı bulabilirseniz, bunun için gidin, ancak dünyayı daha bozuk HTML hackery'lerine maruz bırakmayın.
Soru kesin olarak cevaplanamayacak kadar geniştir. Web sayfası gibi gerçek dünyadaki bir HTML belgesindeki tüm etiketleri kaldırmaktan mı bahsediyorsunuz? Eğer öyleyse, yapmanız gerekenler:
Bu sadece kafamın üstünden - eminim daha fazlası var. Tüm bunları yaptıktan sonra, bazı yerlerde bir araya getirilen kelimeler, cümleler ve paragraflar ve diğerlerinde büyük yararsız boşluk parçaları ile sonuçlanacaksınız.
Ancak, sadece bir parça ile çalıştığınızı ve tüm etiketleri kaldırmayla kurtulabileceğinizi varsayarsak, kullanacağım normal ifade:
@"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>"
Tek ve çift tırnaklı dizeleri kendi alternatifleriyle eşleştirmek, öznitelik değerlerindeki köşeli parantez sorunuyla başa çıkmak için yeterlidir. Ryan'ın cevabındaki normal ifade gibi, özellik adlarını ve etiket içindeki diğer şeyleri açıkça eşleştirmeye gerek görmüyorum; ilk alternatif bunların hepsini halleder.
Bu (?>...)
yapıları merak ediyorsanız , atom gruplarıdır . Normal ifadeyi biraz daha verimli hale getirir, ancak daha da önemlisi, kontrolden çıkmayı engeller, bu da yaptığım gibi alternatif ve iç içe nicelik belirteçleri karıştırdığınızda her zaman dikkat etmeniz gereken bir şeydir. Bunun gerçekten bir sorun olacağını düşünmüyorum, ama bundan bahsetmezsem, başkası yapacağını biliyorum. ;-)
Bu normal ifade elbette mükemmel değil, ama muhtemelen ihtiyacınız olduğu kadar iyi.
Regex regex = new Regex(@"</?\w+((\s+\w+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>", RegexOptions.Singleline);
@JasonTrue doğrudur, HTML etiketlerini sıyırma normal ifadelerle yapılmamalıdır.
HtmlAgilityPack kullanarak HTML etiketlerini çıkarmak oldukça basittir:
public string StripTags(string input) {
var doc = new HtmlDocument();
doc.LoadHtml(input ?? "");
return doc.DocumentNode.InnerText;
}
Jason'ın yanıtını yankılamak istiyorum, ancak bazen bazı Html'leri saf bir şekilde ayrıştırıp metin içeriğini çıkarmanız gerekiyor.
Bunu her zaman eğlenceli ve oyunlar olan zengin bir metin editörü tarafından oluşturulan bazı Html ile yapmam gerekiyordu.
Bu durumda, bazı etiketlerin içeriğini ve yalnızca etiketlerin kendisini kaldırmanız gerekebilir.
Benim durumumda ve etiketler bu karışıma atılmış. Bazıları (çok az) daha az naif uygulamamı faydalı bir başlangıç noktası olarak görebilir.
/// <summary>
/// Removes all html tags from string and leaves only plain text
/// Removes content of <xml></xml> and <style></style> tags as aim to get text content not markup /meta data.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static string HtmlStrip(this string input)
{
input = Regex.Replace(input, "<style>(.|\n)*?</style>",string.Empty);
input = Regex.Replace(input, @"<xml>(.|\n)*?</xml>", string.Empty); // remove all <xml></xml> tags and anything inbetween.
return Regex.Replace(input, @"<(.|\n)*?>", string.Empty); // remove any tags but not there content "<p>bob<span> johnson</span></p>" becomes "bob johnson"
}
<xml>.*(?!</xml>)</xml>
ile benzer şeyler kullanın . Bunlardan ilki, ilk etiket adında yakalanan bir alternatif ve negatif ileri ve son etikette kendisine yapılan referanslarla birleştirilebilir. RegexOptions.SingleLine
<[^>]*>
bu URL'de normal ifade yöntemini deneyin: http://www.dotnetperls.com/remove-html-tags
/// <summary>
/// Remove HTML from string with Regex.
/// </summary>
public static string StripTagsRegex(string source)
{
return Regex.Replace(source, "<.*?>", string.Empty);
}
/// <summary>
/// Compiled regular expression for performance.
/// </summary>
static Regex _htmlRegex = new Regex("<.*?>", RegexOptions.Compiled);
/// <summary>
/// Remove HTML from string with compiled Regex.
/// </summary>
public static string StripTagsRegexCompiled(string source)
{
return _htmlRegex.Replace(source, string.Empty);
}
Ekle .+?
bölgesi <[^>]*>
ve (üzerinde taban bu regex deneyin bu ):
<[^>].+?>
Etiketleri kaldırmak için bu yöntemi kullanın:
public string From_To(string text, string from, string to)
{
if (text == null)
return null;
string pattern = @"" + from + ".*?" + to;
Regex rx = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
MatchCollection matches = rx.Matches(text);
return matches.Count <= 0 ? text : matches.Cast<Match>().Where(match => !string.IsNullOrEmpty(match.Value)).Aggregate(text, (current, match) => current.Replace(match.Value, ""));
}