Вот функция, которую я написал для этой задачи:
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) затем | еще) Я проверяю, является ли следующая часть строки одним из допустимых тегов. Вы можете видеть, что я объединяю строку регулярного выражения с допустимой переменной, которая является приемлемыми именами тегов, разделенными строкой вертикулы, так что любой из терминов будет совпадать. Если это совпадение, вы можете заметить, что я вставил слово «notag», потому что ни один тег не соответствует этому, и если это приемлемо, я хочу оставить его в покое. В противном случае я перехожу к другой части, где я сопоставляю имя любого тега [a-z, A-Z, 0-9] +
Далее я хочу сопоставить 0 или более атрибутов, которые, как я предполагаю, находятся в форме attribute = "value". так что теперь я группирую эту часть, представляющую атрибут, но я использую?:, чтобы предотвратить захват этой группы для скорости: (?: \ s [az, AZ, 0-9, -] + =? (?: ([" »,"]?). ? \ 1?))
Здесь я начинаю с символа пробела, который будет находиться между именами тега и атрибута, затем сопоставляю имя атрибута: [a-z, A-Z, 0-9, -] +
далее я сопоставляю знак равенства, а затем любую кавычку. Я группирую цитату, чтобы она была захвачена, и я могу сделать обратную ссылку позже \ 1, чтобы соответствовать цитате того же типа. Между этими двумя цитатами видно, что я использую точку для сопоставления чего угодно, однако я использую ленивую версию *? вместо жадной версии *, так что она будет соответствовать только следующей кавычке, которая закончит это значение.
далее мы ставим * после закрытия групп круглыми скобками, чтобы он совпадал с несколькими комбинациями attirbute / value (или ни одной). Наконец, мы сопоставляем некоторые пробелы с \ s и заканчивая косой чертой 0 или 1 в тегах для самозакрывающихся тегов в стиле xml.
Вы можете видеть, что я заменяю теги колбасой, потому что я голоден, но вы также можете заменить их пустой строкой, чтобы просто убрать их.