ASP.NET을 사용하여 어떻게 주어진 문자열에서 HTML 태그를 안정적으로 제거 할 수 있습니까 (예 : 정규식을 사용하지 않음)? PHP와 같은 것을 찾고 strip_tags
있습니다.
예:
<ul><li>Hello</li></ul>
산출:
"여보세요"
나는 바퀴를 재발 명하지 않으려 고 노력하고 있지만 지금까지 내 요구를 충족시키는 것을 찾지 못했습니다.
ASP.NET을 사용하여 어떻게 주어진 문자열에서 HTML 태그를 안정적으로 제거 할 수 있습니까 (예 : 정규식을 사용하지 않음)? PHP와 같은 것을 찾고 strip_tags
있습니다.
<ul><li>Hello</li></ul>
"여보세요"
나는 바퀴를 재발 명하지 않으려 고 노력하고 있지만 지금까지 내 요구를 충족시키는 것을 찾지 못했습니다.
답변:
문자열에서 모든 HTML 태그를 제거 하는 경우 정규식에서도 안정적 으로 작동 합니다. 바꾸다:
<[^>]*(>|$)
전역 적으로 빈 문자열로. 나중에 문자열을 정규화하는 것을 잊지 마십시오.
[\s\r\n]+
단일 공간으로 결과를 트리밍합니다. 선택적으로 HTML 문자 엔티티를 실제 문자로 다시 바꿉니다.
참고 :
>
은 속성 값을 허용 합니다. 이 솔루션 은 이러한 값이 발생하면 깨진 마크 업 을 반환합니다."e;
. 나는 그것을 위해 그것을 결합합니다 WebUtility.HtmlDecode
(다시 태그를 제거하지 않을 것입니다). 그것은 다시 수 있기 때문에, 태그 제거 후 사용 >
하고 <
. 예WebUtility.HtmlDecode(Regex.Replace(myTextVariable, "<[^>]*(>|$)", string.Empty))
지금 HTMLAgilityPack을 다운로드하십시오! ;) 링크 다운로드
이를 통해 HTML을로드하고 구문 분석 할 수 있습니다. 그런 다음 DOM을 탐색하고 모든 속성의 내부 값을 추출 할 수 있습니다. 진지하게, 최대 10 줄의 코드가 필요합니다. 가장 훌륭한 무료 .net 라이브러리 중 하나입니다.
다음은 샘플입니다.
string htmlContents = new System.IO.StreamReader(resultsStream,Encoding.UTF8,true).ReadToEnd();
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(htmlContents);
if (doc == null) return null;
string output = "";
foreach (var node in doc.DocumentNode.ChildNodes)
{
output += node.InnerText;
}
text()
노드를 쿼리 하고 내용과 문자열을 다듬을 수도 있습니다 . IEnumerable<string> allText = doc.DocumentNode.SelectNodes("//text()").Select(n => n.InnerText.Trim())
if (doc == null)
수표입니까? 이것은 항상 거짓이지, 그렇지 않습니까?
Regex.Replace(htmlText, "<.*?>", string.Empty);
RegexOptions.SingleLine
.
나는 이것을 asp.net 포럼에 게시했지만 여전히 가장 쉬운 솔루션 중 하나 인 것 같습니다. 가장 빠르거나 가장 효율적이라고 보장하지는 않지만 꽤 신뢰할 수 있습니다. .NET에서는 HTML 웹 컨트롤 개체 자체를 사용할 수 있습니다. 정말 필요한 것은 DIV와 같은 임시 HTML 개체에 문자열을 삽입 한 다음 내장 된 'InnerText'를 사용하여 태그 내에 포함되지 않은 모든 텍스트를 가져 오는 것입니다. 간단한 C # 예제는 아래를 참조하십시오.
System.Web.UI.HtmlControls.HtmlGenericControl htmlDiv = new System.Web.UI.HtmlControls.HtmlGenericControl("div");
htmlDiv.InnerHtml = htmlString;
String plainText = htmlDiv.InnerText;
정규식에서 지옥을이기는 C #으로 꽤 빠른 방법을 작성했습니다. CodeProject 의 기사 에서 호스팅됩니다 .
그것의 장점은 더 나은 성능 사이에서, 이름 및 번호 HTML 엔티티 (같은 그 교체 할 수 있습니다 &amp;
와 &203;
)과 주석 블록 교체 등을.
CodeProject에 대한 관련 기사를 읽어보십시오 .
감사합니다.
HtmlAgilityPack을 사용할 수없는 사용자에게는 .NETs XML 리더가 옵션입니다. 형식이 잘 지정된 HTML에서는 실패 할 수 있으므로 항상 regx를 백업으로 추가하십시오. 이것은 빠르지는 않지만 디버깅을 통해 구식 단계에 좋은 기회를 제공합니다.
public static string RemoveHTMLTags(string content)
{
var cleaned = string.Empty;
try
{
StringBuilder textOnly = new StringBuilder();
using (var reader = XmlNodeReader.Create(new System.IO.StringReader("<xml>" + content + "</xml>")))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Text)
textOnly.Append(reader.ReadContentAsString());
}
}
cleaned = textOnly.ToString();
}
catch
{
//A tag is probably not closed. fallback to regex string clean.
string textOnly = string.Empty;
Regex tagRemove = new Regex(@"<[^>]*(>|$)");
Regex compressSpaces = new Regex(@"[\s\r\n]+");
textOnly = tagRemove.Replace(content, string.Empty);
textOnly = compressSpaces.Replace(textOnly, " ");
cleaned = textOnly;
}
return cleaned;
}
Michael Tiptop의 솔루션이 작동하지 않는다고 불평하는 사람들을 위해 다음은 .Net4 + 방법입니다.
public static string StripTags(this string markup)
{
try
{
StringReader sr = new StringReader(markup);
XPathDocument doc;
using (XmlReader xr = XmlReader.Create(sr,
new XmlReaderSettings()
{
ConformanceLevel = ConformanceLevel.Fragment
// for multiple roots
}))
{
doc = new XPathDocument(xr);
}
return doc.CreateNavigator().Value; // .Value is similar to .InnerText of
// XmlDocument or JavaScript's innerText
}
catch
{
return string.Empty;
}
}
여기에 제안 된 Regex 기반 솔루션을 살펴 보았지만 가장 사소한 경우를 제외하고는 확신을주지 않습니다. 속성의 꺾쇠 괄호 만 있으면 깨질 수 있습니다. 잘못된 형식의 HTML은 말할 것도 없습니다. 그리고 같은 엔티티는 어떻습니까?&
어떻습니까? HTML을 일반 텍스트로 변환하려면 엔터티도 디코딩해야합니다.
그래서 아래 방법을 제안합니다.
HtmlAgilityPack을 사용하는 이 확장 메서드는 html 조각에서 모든 HTML 태그를 효율적으로 제거합니다. 또한 &
. 각 텍스트 항목 사이에 새 줄이있는 내부 텍스트 항목 만 반환합니다.
public static string RemoveHtmlTags(this string html)
{
if (String.IsNullOrEmpty(html))
return html;
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
if (doc.DocumentNode == null || doc.DocumentNode.ChildNodes == null)
{
return WebUtility.HtmlDecode(html);
}
var sb = new StringBuilder();
var i = 0;
foreach (var node in doc.DocumentNode.ChildNodes)
{
var text = node.InnerText.SafeTrim();
if (!String.IsNullOrEmpty(text))
{
sb.Append(text);
if (i < doc.DocumentNode.ChildNodes.Count - 1)
{
sb.Append(Environment.NewLine);
}
}
i++;
}
var result = sb.ToString();
return WebUtility.HtmlDecode(result);
}
public static string SafeTrim(this string str)
{
if (str == null)
return null;
return str.Trim();
}
당신이 정말로 심각한 경우에, 당신은 너무 (특정 HTML 태그의 내용을 무시하려는 것 <script>
, <style>
, <svg>
, <head>
, <object>
그들은 아마도 우리가 후 인 의미에서 읽을 수있는 콘텐츠가 포함되지 않기 때문에 마음에 와서!). 당신이하는 일은 당신의 상황과 얼마나 멀리 가고자 하는가에 따라 다르지만, HtmlAgilityPack을 사용하면 선택된 태그를 화이트리스트 나 블랙리스트에 올리는 것은 매우 사소한 일입니다.
당신이 HTML 페이지에 콘텐츠를 다시 렌더링하는 경우 XSS 취약점 및 이해하도록 어떻게 그것을 방지하는 방법을 - 즉, 항상 HTML 페이지 (에 다시 렌더링됩니다 사용자가 입력 한 텍스트 인코딩 >
이된다 >
등).
두 번째 매개 변수, 즉 일부 태그를 유지하려면 HTMLagilityPack을 사용하여 다음과 같은 코드가 필요할 수 있습니다.
public string StripTags(HtmlNode documentNode, IList keepTags)
{
var result = new StringBuilder();
foreach (var childNode in documentNode.ChildNodes)
{
if (childNode.Name.ToLower() == "#text")
{
result.Append(childNode.InnerText);
}
else
{
if (!keepTags.Contains(childNode.Name.ToLower()))
{
result.Append(StripTags(childNode, keepTags));
}
else
{
result.Append(childNode.OuterHtml.Replace(childNode.InnerHtml, StripTags(childNode, keepTags)));
}
}
}
return result.ToString();
}
이 페이지에 대한 자세한 설명 : http://nalgorithm.com/2015/11/20/strip-html-tags-of-an-html-in-c-strip_html-php-equivalent/
HtmlAgilityPack의 대안 인 AngleSharp 로도이 작업을 수행 할 수 있습니다 (HAP가 나쁘지 않음). HTML 소스에서 텍스트를 가져 오는 것이 HAP보다 사용하기 쉽습니다.
var parser = new HtmlParser();
var htmlDocument = parser.ParseDocument(source);
var text = htmlDocument.Body.Text();
HAP보다 "더 나은"사례를 만드는 주요 기능 섹션을 살펴볼 수 있습니다 . 나는 대부분의 경우 현재 질문에 대해 과도하다고 생각하지만 여전히 흥미로운 대안입니다.
간단히 사용 string.StripHTML();