C #에서 & nbsp를 포함한 문자열에서 HTML 태그 제거


83

C #에서 regex를 사용하여 & nbsp를 포함한 모든 HTML 태그를 제거하려면 어떻게해야합니까? 내 문자열은 다음과 같습니다.

  "<div>hello</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div>"

9
정규식을 사용하지 말고 HTML Agility Pack을 확인하십시오. stackoverflow.com/questions/846994/how-to-use-html-agility-pack

Tim에게 감사합니다.하지만 응용 프로그램이 상당히 크고 손상되지 않았으므로 html 민첩성 팩을 추가하거나 다운로드 할 수 없습니다.
rampuriyaaa 2013 년

답변:


196

HTML 파서 지향 솔루션을 사용하여 태그를 필터링 할 수없는 경우 여기에 간단한 정규식이 있습니다.

string noHTML = Regex.Replace(inputHTML, @"<[^>]+>|&nbsp;", "").Trim();

이상적으로는 여러 공백을 처리하는 정규식 필터를 통해 또 다른 패스를 만들어야합니다.

string noHTMLNormalised = Regex.Replace(noHTML, @"\s{2,}", " ");

아직 필요한만큼 테스트하지는 않았지만 예상했던 것보다 더 잘 작동했습니다. 아래에 작성한 방법을 게시하겠습니다.
Don Rolling

(A 게으른 경기 <[^>]+?>@ 데이비드 S. 당)이 빠르게 조금 만들지 만, 단지 라이브 프로젝트에이 솔루션을 사용 할 수 - : +1 매우 행복
코딩 사라

Regex.Replace (inputHTML, @ "<[^>] +> | & nbsp | \ n;", "") .Trim (); \ n 제거하기되지 않는다
마헤 Malpani

3
빈 문자열보다는 공백을 광고하는 것이 좋습니다. 어떤 식 으로든 추가 공백을 잡습니다Regex.Replace(inputHTML, @"<[^>]+>|&nbsp;", " ")
Tauseef

2
@Tauseef 첫 번째 교체 호출에서 공백을 사용하면 원래 입력에 공백이 없었던 곳에 공백이 남게 될 수 있습니다. Sound<b>Cloud</b>입력으로 수신한다고 가정하십시오 . 그것이 HTML로 표시되는 방식이기 때문에 Sound Cloud제거되어야하는 동안 끝날 것입니다 SoundCloud.
Ravi Thapliyal 2015 년

31

@Ravi Thapliyal의 코드를 가져 와서 방법을 만들었습니다. 간단하고 모든 것을 정리하지는 않을 수도 있지만 지금까지 필요한 작업을 수행하고 있습니다.

public static string ScrubHtml(string value) {
    var step1 = Regex.Replace(value, @"<[^>]+>|&nbsp;", "").Trim();
    var step2 = Regex.Replace(step1, @"\s{2,}", " ");
    return step2;
}

16

이 기능을 한동안 사용하고 있습니다. 던질 수있는 지저분한 html을 거의 제거하고 텍스트는 그대로 둡니다.

        private static readonly Regex _tags_ = new Regex(@"<[^>]+?>", RegexOptions.Multiline | RegexOptions.Compiled);

        //add characters that are should not be removed to this regex
        private static readonly Regex _notOkCharacter_ = new Regex(@"[^\w;&#@.:/\\?=|%!() -]", RegexOptions.Compiled);

        public static String UnHtml(String html)
        {
            html = HttpUtility.UrlDecode(html);
            html = HttpUtility.HtmlDecode(html);

            html = RemoveTag(html, "<!--", "-->");
            html = RemoveTag(html, "<script", "</script>");
            html = RemoveTag(html, "<style", "</style>");

            //replace matches of these regexes with space
            html = _tags_.Replace(html, " ");
            html = _notOkCharacter_.Replace(html, " ");
            html = SingleSpacedTrim(html);

            return html;
        }

        private static String RemoveTag(String html, String startTag, String endTag)
        {
            Boolean bAgain;
            do
            {
                bAgain = false;
                Int32 startTagPos = html.IndexOf(startTag, 0, StringComparison.CurrentCultureIgnoreCase);
                if (startTagPos < 0)
                    continue;
                Int32 endTagPos = html.IndexOf(endTag, startTagPos + 1, StringComparison.CurrentCultureIgnoreCase);
                if (endTagPos <= startTagPos)
                    continue;
                html = html.Remove(startTagPos, endTagPos - startTagPos + endTag.Length);
                bAgain = true;
            } while (bAgain);
            return html;
        }

        private static String SingleSpacedTrim(String inString)
        {
            StringBuilder sb = new StringBuilder();
            Boolean inBlanks = false;
            foreach (Char c in inString)
            {
                switch (c)
                {
                    case '\r':
                    case '\n':
                    case '\t':
                    case ' ':
                        if (!inBlanks)
                        {
                            inBlanks = true;
                            sb.Append(' ');
                        }   
                        continue;
                    default:
                        inBlanks = false;
                        sb.Append(c);
                        break;
                }
            }
            return sb.ToString().Trim();
        }

확인하기 위해 SingleSpacedTrim () 함수는 문자열 noHTMLNormalised = Regex.Replace (noHTML, @ "\ s {2,}", ""); Ravi Thapliyal의 대답에서?
Jimmy

@Jimmy 내가 볼 수있는 한, 정규식은 SingleSpacedTrim ()처럼 단일 탭이나 줄 바꿈을 잡지 않습니다. 그래도 바람직한 효과가 될 수 있습니다.이 경우 필요에 따라 케이스를 제거하면됩니다.
David S.

좋지만 " notOkCharacter "목록에 없더라도 작은 따옴표와 큰 따옴표도 공백으로 대체하는 것 같습니다 . 아니면 뭔가 빠졌습니까? 디코딩 / 인코딩 모임의이 부분이 처음에 호출됩니까? 이 문자를 그대로 유지하려면 무엇이 필요합니까?
vm370

4
var noHtml = Regex.Replace(inputHTML, @"<[^>]*(>|$)|&nbsp;|&zwnj;|&raquo;|&laquo;", string.Empty).Trim();

1

@RaviThapliyal & @Don Rolling의 코드를 사용했지만 약간 수정했습니다. & nbsp를 빈 문자열로 바꾸고 대신 & nbsp를 공백으로 바꿔야하므로 추가 단계를 추가했습니다. 그것은 나를 위해 매력처럼 작동했습니다.

public static string FormatString(string value) {
    var step1 = Regex.Replace(value, @"<[^>]+>", "").Trim();
    var step2 = Regex.Replace(step1, @"&nbsp;", " ");
    var step3 = Regex.Replace(step2, @"\s{2,}", " ");
    return step3;
}

스택 오버플로에 의해 형식이 지정 되었기 때문에 세미콜론없이 & nbps를 사용했습니다.


0

이:

(<.+?> | &nbsp;)

모든 태그와 일치하거나 &nbsp;

string regex = @"(<.+?>|&nbsp;)";
var x = Regex.Replace(originalString, regex, "").Trim();

그런 다음 x = hello


0

Html 문서를 삭제하려면 많은 까다로운 작업이 필요합니다. 이 패키지는 아마도 도움이 될 것입니다 : https://github.com/mganss/HtmlSanitizer


HTML을 정규화하는 것보다 XSS 공격이 더
많다고

1
@Revious 나는 당신이 옳다고 생각합니다. 아마도 내 대답은 html 태그를 제거하는 목적을 언급하지 않았기 때문에 OP의 질문과 많이 관련이 없습니다. 그러나 많은 경우와 같이 공격을 방지하는 것이 목적이라면 이미 개발 된 살균제를 사용하는 것이 더 나은 방법 일 수 있습니다. BTW 나는 html 정규화 의 의미에 대해 알지 못합니다 .
Ehsan88

0

HTML은 기본 형식으로 XML입니다. XmlDocument 개체의 텍스트를 구문 분석하고 루트 요소에서 InnerText를 호출하여 텍스트를 추출 할 수 있습니다. 이렇게하면 모든 형식의 모든 HTML 태그가 제거되고 & lt; & nbsp; 한 번에 모두.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.