ฉันจะใช้นิพจน์ทั่วไป C # เพื่อแทนที่ / ลบแท็ก HTML ทั้งหมดรวมถึงวงเล็บเหลี่ยมได้อย่างไร มีคนช่วยฉันด้วยรหัสได้ไหม
ฉันจะใช้นิพจน์ทั่วไป C # เพื่อแทนที่ / ลบแท็ก HTML ทั้งหมดรวมถึงวงเล็บเหลี่ยมได้อย่างไร มีคนช่วยฉันด้วยรหัสได้ไหม
คำตอบ:
ตามที่ระบุไว้ก่อนหน้านี้คุณไม่ควรใช้นิพจน์ทั่วไปเพื่อประมวลผลเอกสาร XML หรือ HTML พวกเขาทำงานได้ไม่ดีกับเอกสาร HTML และ XML เนื่องจากไม่มีวิธีที่จะแสดงโครงสร้างแบบซ้อนในลักษณะทั่วไป
คุณสามารถใช้สิ่งต่อไปนี้
String result = Regex.Replace(htmlDocument, @"<[^>]*>", String.Empty);
สิ่งนี้จะได้ผลในกรณีส่วนใหญ่ แต่จะมีบางกรณี (เช่น CDATA ที่มีวงเล็บเหลี่ยม) ซึ่งจะไม่ทำงานอย่างที่คาดไว้
คำตอบที่ถูกต้องคือไม่ทำอย่างนั้นให้ใช้HTML Agility แพ็ค
แก้ไขเพื่อเพิ่ม:
ในการขโมยความคิดเห็นจากเจสซีอย่างไร้ยางอายและเพื่อหลีกเลี่ยงการถูกกล่าวหาว่าตอบคำถามไม่ดีตลอดเวลานี่เป็นตัวอย่างที่ง่ายและเชื่อถือได้โดยใช้ HTML Agility Pack ที่ทำงานร่วมกับ HTML ที่ไม่สมบูรณ์และมีรูปแบบไม่แน่นอนที่สุด:
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 เนื่องจาก HTML ไม่สามารถแยกวิเคราะห์ได้อย่างถูกต้องหากไม่มีการรับรู้บริบทที่เจ็บปวดอย่างมากที่จะให้แม้ในเอ็นจิน regex แบบไม่เปลี่ยนตำแหน่ง คุณสามารถไปที่นั่นด้วย RegEx แต่คุณต้องทำการตรวจสอบด้วยตนเอง
Html Agility Pack สามารถมอบโซลูชันที่มีประสิทธิภาพให้กับคุณซึ่งจะช่วยลดความจำเป็นในการแก้ไขความผิดปกติที่อาจเกิดขึ้นจากการใช้ HTML อย่างไร้เดียงสาอย่างไร้เหตุผล
การแสดงออกปกติอาจทำให้คุณได้รับสิ่งที่คุณต้องการเป็นส่วนใหญ่ แต่มันจะล้มเหลวในกรณีที่พบบ่อยมาก หากคุณสามารถหา parser ที่ดีกว่าหรือเร็วกว่า HTML Agility Pack ไปได้เลย แต่โปรดอย่าทำให้โลกนี้แฮ็ค HTML ที่เสียหายมากขึ้น
คำถามกว้างเกินไปที่จะตอบอย่างชัดเจน คุณกำลังพูดถึงการลบแท็กทั้งหมดออกจากเอกสาร HTML ในโลกแห่งความเป็นจริงเช่นหน้าเว็บหรือไม่? ถ้าเป็นเช่นนั้นคุณจะต้อง:
นั่นเป็นเพียงส่วนหัวของฉัน - ฉันแน่ใจว่ามีอีก เมื่อคุณทำทุกอย่างเสร็จแล้วคุณจะจบลงด้วยคำประโยคและย่อหน้าที่รวมตัวกันในบางสถานที่และช่องว่างขนาดใหญ่ที่ไร้ประโยชน์ในที่อื่น ๆ
แต่สมมติว่าคุณกำลังทำงานกับส่วนย่อย ๆ และคุณสามารถลบออกได้โดยง่ายเพียงแค่ลบแท็กทั้งหมดนี่คือ regex ที่ฉันจะใช้:
@"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>"
การจับคู่สตริงเดี่ยวและเครื่องหมายคำพูดคู่ในทางเลือกของตนเองเพียงพอที่จะจัดการกับปัญหาของวงเล็บเหลี่ยมในค่าแอตทริบิวต์ ฉันไม่เห็นความต้องการใด ๆ ที่จะจับคู่ชื่อแอตทริบิวต์และสิ่งอื่น ๆ ภายในแท็กอย่างชัดเจนเช่นเดียวกับ regex ในคำตอบของ Ryan ทางเลือกแรกจัดการทั้งหมดนั้น
ในกรณีที่คุณสงสัยเกี่ยวกับผู้(?>...)
สร้างพวกเขากำลังกลุ่มอะตอม พวกมันทำให้ Regex มีประสิทธิภาพเพิ่มขึ้นเล็กน้อย แต่ที่สำคัญกว่านั้นคือป้องกันการย้อนรอยกลับแบบควบคุมไม่ได้ซึ่งเป็นสิ่งที่คุณควรระวังเมื่อคุณผสมการสับเปลี่ยนและการเรียงซ้อนปริมาณที่ฉันทำ ฉันไม่คิดว่าจะเป็นปัญหาที่นี่ แต่ฉันรู้ว่าถ้าฉันไม่พูดถึงมันคนอื่นจะ ;-)
แน่นอนว่า regex นี้ไม่สมบูรณ์แบบ แต่อาจดีเท่าที่คุณต้องการ
Regex regex = new Regex(@"</?\w+((\s+\w+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>", RegexOptions.Singleline);
@JasonTrue ถูกต้องการลอกแท็ก HTML นั้นไม่ควรกระทำผ่านการแสดงออกปกติ
การแท็ก HTML โดยใช้ HtmlAgilityPack นั้นค่อนข้างง่าย
public string StripTags(string input) {
var doc = new HtmlDocument();
doc.LoadHtml(input ?? "");
return doc.DocumentNode.InnerText;
}
ฉันต้องการที่จะสะท้อนการตอบสนองของ Jason แม้ว่าบางครั้งคุณจำเป็นต้องแยกวิเคราะห์ Html อย่างไร้เดียงสาและดึงเนื้อหาข้อความออกมา
ฉันต้องทำสิ่งนี้กับ Html ที่สร้างขึ้นโดยโปรแกรมแก้ไขข้อความที่หลากหลายสนุกและเล่นเกมเสมอ
ในกรณีนี้คุณอาจต้องลบเนื้อหาของแท็กบางส่วนรวมถึงแท็กด้วยตนเอง
ในกรณีของฉันและแท็กถูกโยนลงในส่วนประสมนี้ บางคนอาจพบว่าการเริ่มต้นใช้งาน (ไร้เดียงสาเล็กน้อย) ของฉันเป็นจุดเริ่มต้นที่มีประโยชน์
/// <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>
กับRegexOptions.SingleLine
ตัวดัดแปลงสำหรับสองตัวแรกและ<[^>]*>
ตัวสุดท้าย คนแรกยังสามารถรวมกันโดยการสลับการจับภาพในชื่อแท็กแรกและ backreferences ไปในแท็ก lookahead เชิงลบและแท็กสุดท้าย
ลองวิธีการแสดงออกปกติที่ URL นี้: 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);
}
ใช้สิ่งนี้ ..
@"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>"
ใช้วิธีนี้เพื่อลบแท็ก:
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, ""));
}