특정 화이트리스트를 제외한 모든 HTML 태그를 필터링하려면 어떻게 해야 합니까?
이거는.NET. IgnoreCase가 설정되어 있고 MultiLine이 설정되어 있지 않습니다.
보통 정규식은 괜찮은 편인데, 카페인이 부족한 것 같아요
사용자는 HTML 인코딩 엔티티(<lt;, <amp; 등)를 입력하고 다음 HTML 태그를 사용할 수 있습니다.
u, i, b, h3, h4, br, a, img
추가 공간이 있든 없든 <br/> 및 <img/>는 자동으로 닫을 수 있지만 필수는 아닙니다.
원하는 항목:
- 위에 나열된 태그 이외의 시작 및 끝 HTML 태그를 모두 제거합니다.
- 앵커가 href를 가질 수 있는 경우를 제외하고 나머지 태그에서 특성을 제거합니다.
지금까지의 검색 패턴(빈 문자열로 대체됨):
<(?!i|b|h3|h4|a|img|/i|/b|/h3|/h4|/a|/img)[^>]+>
이것은 제가 원하는 시작 태그와 끝 태그를 제외한 모든 태그를 제거하는 것처럼 보이지만, 세 가지 문제가 있습니다.
- 허용된 각 태그의 끝 태그 버전을 포함해야 하는 것은 위험합니다.
- 속성은 살아남습니다.한 번의 교체로 이러한 현상이 발생할 수 있습니까?
- 허용된 태그 이름으로 시작하는 태그가 통과합니다.예: "<abbrev>" 및 "<iframe>".
다음 제안된 패턴은 속성이 없는 태그를 제거하지 않습니다.
</?(?!i|b|h3|h4|a|img)\b[^>]*>
아래에서 언급한 바와 같이, ">"는 속성값으로 합법적이지만, 저는 그것을 지지하지 않는다고 봐도 무방합니다.또한 걱정할 CDATA 블록 등이 없을 것입니다.HTML만 조금.
지금까지 가장 좋은 답변은 루커스의 답변입니다, 감사합니다!그의 패턴은 다음과 같습니다(PRE가 나에게 더 잘 작동하기를 바랍니다).
static string SanitizeHtml(string html)
{
string acceptable = "script|link|title";
string stringPattern = @"</?(?(?=" + acceptable + @")notag|[a-zA-Z0-9]+)(?:\s[a-zA-Z0-9\-]+=?(?:([""']?).*?\1?)?)*\s*/?>";
return Regex.Replace(html, stringPattern, "sausage");
}
이 답변에 대해 여전히 약간의 수정이 가능할 것으로 생각합니다.
이것은 "허용 가능" 변수에 "!--"을 추가하고 식의 끝에 선택적인 후행 "\s--"를 허용하도록 약간의 변경을 가함으로써 간단한 HTML 주석(태그 자체를 포함하지 않는 주석)을 캡처하도록 수정될 수 있다고 생각합니다.
속성 사이에 공백 문자가 여러 개 있는 경우(예: 속성 사이에 줄 바꿈과 탭이 있는 대량 형식의 HTML) 이 손상될 수 있습니다.
2009-07-23 편집: 다음은 (VB에서) 사용한 최종 솔루션입니다.NET):
Dim AcceptableTags As String = "i|b|u|sup|sub|ol|ul|li|br|h2|h3|h4|h5|span|div|p|a|img|blockquote"
Dim WhiteListPattern As String = "</?(?(?=" & AcceptableTags & _
")notag|[a-zA-Z0-9]+)(?:\s[a-zA-Z0-9\-]+=?(?:([""']?).*?\1?)?)*\s*/?>"
html = Regex.Replace(html, WhiteListPattern, "", RegExOptions.Compiled)
주의할 점은 A 태그의 HREF 속성이 여전히 스크러빙되므로 이상적이지 않다는 것입니다.
이 작업을 위해 작성한 기능은 다음과 같습니다.
static string SanitizeHtml(string html)
{
string acceptable = "script|link|title";
string stringPattern = @"</?(?(?=" + acceptable + @")notag|[a-zA-Z0-9]+)(?:\s[a-zA-Z0-9\-]+=?(?:(["",']?).*?\1?)?)*\s*/?>";
return Regex.Replace(html, stringPattern, "sausage");
}
편집: 어떤 이유에서인지 이전 답변에 대한 수정 사항을 별도의 답변으로 게시하여 통합합니다.
정규식이 조금 길기 때문에 제가 조금 설명하겠습니다.
첫 번째 부분은 열린 괄호와 0개 또는 1개의 슬래시(밀착 태그인 경우)와 일치합니다.
다음으로 미래를 내다보는 if-then 구성을 볼 수 있습니다. (?(?)=SomeTag) then |else) 문자열의 다음 부분이 허용 가능한 태그 중 하나인지 확인합니다.정규식 문자열을 허용 가능한 변수와 연결하는 것을 볼 수 있습니다. 허용 가능한 변수는 용어가 일치하도록 verticle bar로 구분된 허용 가능한 태그 이름입니다.만약 그것이 일치한다면, 당신은 제가 "notag"라는 단어를 넣는 것을 볼 수 있습니다. 왜냐하면 어떤 태그도 그것과 일치하지 않을 것이고 받아들일 수 있다면, 저는 그것을 그냥 두고 싶습니다.그렇지 않으면 태그 이름과 일치하는 다른 부분으로 이동합니다 [a-z,A-Z,0-9]+
다음으로 0개 이상의 속성을 일치시키고 싶습니다. 속성은 attribute="value" 형식입니다. 따라서 이제 속성을 나타내는 이 부분을 그룹화하지만 속도를 위해 이 그룹이 캡처되는 것을 방지하기 위해 ?:(?\s[a-z, A-Z, 0-9, -]+=?(?('[", '?).\1?)
여기서 태그와 속성 이름 사이에 있는 공백 문자로 시작한 다음 속성 이름을 일치시킵니다. [a-z, A-Z, 0-9, -]+
다음에는 등호를 일치시키고 그 다음에는 따옴표를 붙입니다.인용문이 캡처되도록 그룹화하고 나중에 백레퍼런스를 수행하여 동일한 유형의 인용문과 일치시킬 수 있습니다.이 두 인용문 사이에는 기간을 사용하여 모든 항목을 일치시키지만 탐욕스러운 버전 * 대신 게으른 버전 *?을 사용하여 이 값을 끝낼 다음 인용문에만 일치시킵니다.
다음으로 여러 속성/값 조합(또는 없음)과 일치하도록 괄호를 사용하여 그룹을 닫은 후 *를 추가합니다.마지막으로 xml 스타일 자체 닫기 태그에 대한 태그의 일부 공백을 \s 및 0 또는 1 끝 슬래시와 일치시킵니다.
제가 태그를 소시지로 대체하는 것을 보실 수 있습니다. 배가 고파서요. 하지만 여러분도 빈 끈으로 대체해서 제거할 수 있습니다.
다음은 HTML 태그 필터링에 대한 좋은 작업 예입니다.
속성은 정규 표현식을 사용하여 HTML로 작업하는 데 있어 주요 문제입니다. 잠재적인 속성의 수가 매우 많고, 대부분이 선택적이며, 어떤 순서로도 나타날 수 있다는 점과 인용된 속성 값에서 ">"가 합법적인 문자라는 점을 고려하십시오.이 모든 것을 고려하기 시작하면 이 모든 것을 처리해야 하는 정규식은 순식간에 관리할 수 없게 됩니다.
대신 이벤트 기반 HTML 파서를 사용하거나 DOM 트리를 제공하는 파서를 사용합니다.
현재 솔루션은 허용 가능한 태그로 시작하는 태그를 허용합니다.따라서 "b"가 허용 가능한 태그라면 "blink"도 허용됩니다.큰 문제는 아니지만 HTML을 필터링하는 방법에 대해 엄격하다면 고려해야 할 사항입니다. "s"를 허용하는 태그로 허용하고 싶지 않을 것입니다. "script"를 허용하기 때문입니다.
HtmlRuleSanitizer는 HTML Agility Pack 위에 구축되었으며 태그를 검사하기 위한 간단한 구문을 가지고 있습니다.
방법HtmlSanitizer.SimpleHtml5Sanitizer()
필요한 모든 것이 들어 있는 살균제를 생성하지만 보다 역동적인 접근 방식이 있습니다.
public static string GetLimitedHtml(string value)
{
var sanitizer = HtmlSanitizer.SimpleHtml5Sanitizer();
var allowed = new string[] {"br", "h1", "h2", "h3", "h4", "h5", "h6", "small", "strike", "strong", "b"};
foreach (var tag in allowed)
{
sanitizer.Tag(tag);
}
return sanitizer.Sanitize(value);
}
경계 \b라는 단어를 추가하는 것이 효과가 없었던 이유는 당신이 미리 보기 안에 넣지 않았기 때문입니다.따라서, \b는 < 뒤에 시도됩니다. 여기서 <이 HTML 태그를 시작하면 항상 일치합니다.
다음과 같이 미리 보기 안에 넣습니다.
<(?!/?(i|b|h3|h4|a|img)\b)[^>]+>
또한 각 태그가 아닌 태그 목록 앞에 /를 배치하는 방법도 보여줍니다.
원래는 값을 선택적으로 만들 생각이었지만, 추가한 것을 볼 수 있기 때문에 수행하지 않았습니다.?
등호 뒤에 표시하고 일치하는 값 부분을 그룹화합니다.를 추가합니다.?
해당 그룹(경동맥으로 표시됨) 뒤에 선택 사항으로 지정합니다.나는 지금 컴파일러에 없지만, 이것이 작동하는지 확인합니다.
@"</?(?(?=" + acceptable + @")notag|[a-z,A-Z,0-9]+)(?:\s[a-z,A-Z,0-9,\-]+=?(?:(["",']?).*?\1?)?)*\s*/?>";
^
/// <summary>
/// Trims the ignoring spacified tags
/// </summary>
/// <param name="text">the text from which html is to be removed</param>
/// <param name="isRemoveScript">specify if you want to remove scripts</param>
/// <param name="ignorableTags">specify the tags that are to be ignored while stripping</param>
/// <returns>Stripped Text</returns>
public static string StripHtml(string text, bool isRemoveScript, params string[] ignorableTags)
{
if (!string.IsNullOrEmpty(text))
{
text = text.Replace("<", "<");
text = text.Replace(">", ">");
string ignorePattern = null;
if (isRemoveScript)
{
text = Regex.Replace(text, "<script[^<]*</script>", string.Empty, RegexOptions.IgnoreCase);
}
if (!ignorableTags.Contains("style"))
{
text = Regex.Replace(text, "<style[^<]*</style>", string.Empty, RegexOptions.IgnoreCase);
}
foreach (string tag in ignorableTags)
{
//the character b spoils the regex so replace it with strong
if (tag.Equals("b"))
{
text = text.Replace("<b>", "<strong>");
text = text.Replace("</b>", "</strong>");
if (ignorableTags.Contains("strong"))
{
ignorePattern = string.Format("{0}(?!strong)(?!/strong)", ignorePattern);
}
}
else
{
//Create ignore pattern fo the tags to ignore
ignorePattern = string.Format("{0}(?!{1})(?!/{1})", ignorePattern, tag);
}
}
//finally add the ignore pattern into regex <[^<]*> which is used to match all html tags
ignorePattern = string.Format(@"<{0}[^<]*>", ignorePattern);
text = Regex.Replace(text, ignorePattern, "", RegexOptions.IgnoreCase);
}
return text;
}
언급URL : https://stackoverflow.com/questions/307013/how-do-i-filter-all-html-tags-except-a-certain-whitelist
'programing' 카테고리의 다른 글
다른 테이블의 필드에서 한 테이블의 SQL 업데이트 필드 (0) | 2023.05.15 |
---|---|
Python의 함수 체인 (0) | 2023.05.15 |
Xcode에서 기호 파일 처리 (0) | 2023.05.10 |
상황에 맞는 메뉴의 메뉴 항목에서 요소 이름 바인딩 (0) | 2023.05.10 |
Xib 파일에서 사용자 지정 UITableViewCells를 로드하는 방법은 무엇입니까? (0) | 2023.05.10 |