Как использовать регулярное выражение для сопоставления строки кодировки в HTML? - PullRequest
8 голосов
/ 11 августа 2010

Пример HTML-кода:

<meta http-equiv="Content-type" content="text/html;charset=utf-8" />

Я хочу использовать RegEx для извлечения информации о кодировке (т. Е. Здесь это "utf-8")

(я использую C #)

Ответы [ 9 ]

16 голосов
/ 27 мая 2012

В моем ответе представлена ​​более надежная версия @ Floyd's и, по мере возможности, адресован тестовый пример @ You, где для предотвращения этого используется отрицательный прогноз.На самом деле я могу вспомнить только один уместный случай (вариант примера @ You), когда он дает ложный положительный результат, но я думаю, что это будет довольно редко.Ожидается, что выражения будут выполняться с флагом без учета регистра и были протестированы с использованием java.util.regex и JRegex .

Группы захвата автоматически обрезаются и никогда не включаюткавычки, ни другие символы тегов, такие как "/" или ">".Во втором выражении есть 2 группы захвата;первое - это значение типа содержимого, которое может быть пустым (т. е. при использовании атрибута charset), а второе - значением charset, которое всегда будет непустым (если только значение charset не остается буквально пустым по какой-то странной причине).).

Регулярное выражение для сопоставления / группировки только значений набора символов - обрезается, пропускает кавычки

<meta(?!\s*(?:name|value)\s*=)[^>]*?charset\s*=[\s"']*([^\s"'/>]*)

То же, что и выше, но также совпадает / группирует тип содержимого (необязательно) и набор символов (обязательно)значения, обрезанные, пропускает кавычки.Незначительное предостережение - пропущено сопоставление отдельного значения типа контента, т. Е. «Text / html»

<meta(?!\s*(?:name|value)\s*=)(?:[^>]*?content\s*=[\s"']*)?([^>]*?)[\s"';]*charset\s*=[\s"']*([^\s"'/>]*)

Контрольные примеры (все проходы, кроме самого последнего) ...

<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" />
<meta http-equiv='Content-Type' content='text/html;charset=iso-8859-1'/>
<meta http-equiv='Content-Type' content='text/html;charset=iso-8859-1' />
<meta http-equiv=Content-Type content=text/html;charset=iso-8859-1/>
<meta http-equiv=Content-Type content=text/html;charset=iso-8859-1 />
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" >
<meta http-equiv='Content-Type' content='text/html;charset=iso-8859-1'>
<meta http-equiv='Content-Type' content='text/html;charset=iso-8859-1' >
<meta http-equiv=Content-Type content=text/html;charset=iso-8859-1>
<meta http-equiv=Content-Type content=text/html;charset=iso-8859-1 >

<meta http-equiv="Content-Type" content="text/html;charset='iso-8859-1'">
<meta http-equiv="Content-Type" content="'text/html;charset=iso-8859-1'">
<meta http-equiv="Content-Type" content="'text/html';charset='iso-8859-1'">
<meta http-equiv='Content-Type' content='text/html;charset="iso-8859-1"'>
<meta http-equiv='Content-Type' content='"text/html;charset=iso-8859-1"'>
<meta http-equiv='Content-Type' content='"text/html";charset="iso-8859-1"'>

<meta http-equiv="Content-Type" content="text/html;;;charset=iso-8859-1">
<meta http-equiv="Content-Type" content="text/html;;;charset='iso-8859-1'">
<meta http-equiv="Content-Type" content="'text/html;;;charset=iso-8859-1'">
<meta http-equiv="Content-Type" content="'text/html';;;charset='iso-8859-1'">
<meta http-equiv='Content-Type' content='text/html;;;charset=iso-8859-1'>
<meta http-equiv='Content-Type' content='text/html;;;charset="iso-8859-1"'>
<meta http-equiv='Content-Type' content='"text/html;;;charset=iso-8859-1"'>
<meta http-equiv='Content-Type' content='"text/html";;;charset="iso-8859-1"'>

<meta  http-equiv  =  "  Content-Type  "  content  =  "  '  text/html  '  ;  ;;  '  ;  '  '  ;  '  ;  ' ;;  ;  charset  =  '  iso-8859-1  '  "  >
<meta  content  =  "  '  text/html  '  ;  ;;  '  ;  '  '  ;  '  ;  ' ;;  ;  charset  =  '  iso-8859-1  '  "  http-equiv  =  "  Content-Type  "  >
<meta  http-equiv  =  Content-Type  content  =  text/html;charset=iso-8859-1  >
<meta  content  =  text/html;charset=iso-8859-1  http-equiv  =  Content-Type  >
<meta  http-equiv  =  Content-Type  content  =  text/html  ;  charset  =  iso-8859-1  >
<meta  content  =  text/html  ;  charset  =  iso-8859-1  http-equiv  =  Content-Type  >
<meta  http-equiv  =  Content-Type  content  =  text/html  ;;;  charset  =  iso-8859-1  >
<meta  content  =  text/html  ;;;  charset  =  iso-8859-1  http-equiv  =  Content-Type  >
<meta  http-equiv  =  Content-Type  content  =  text/html  ;  ;  ;  charset  =  iso-8859-1  >
<meta  content  =  text/html  ;  ;  ;  charset  =  iso-8859-1  http-equiv  =  Content-Type  >

<meta charset="utf-8"/>
<meta charset="utf-8" />
<meta charset='utf-8'/>
<meta charset='utf-8' />
<meta charset=utf-8/>
<meta charset=utf-8 />
<meta charset="utf-8">
<meta charset="utf-8" >
<meta charset='utf-8'>
<meta charset='utf-8' >
<meta charset=utf-8>
<meta charset=utf-8 >

<meta  charset  =  "  utf-8  "  >
<meta  charset  =  '  utf-8  '  >
<meta  charset  =  "  utf-8  '  >
<meta  charset  =  '  utf-8  "  >
<meta  charset  =  "  utf-8     >
<meta  charset  =  '  utf-8     >
<meta  charset  =     utf-8  '  >
<meta  charset  =     utf-8  "  >
<meta  charset  =     utf-8     >
<meta  charset  =     utf-8    />

<meta name="title" value="charset=utf-8 — is it really useful (yep)?">
<meta value="charset=utf-8 — is it really useful (yep)?" name="title">
<meta name="title" content="charset=utf-8 — is it really useful (yep)?">
<meta name="charset=utf-8" content="charset=utf-8 — is it really useful (yep)?">

<meta content="charset=utf-8 — is it really useful (nope, not here, but gotta admit pretty robust otherwise)?" name="title">
8 голосов
/ 11 августа 2010

Это регулярное выражение:

<meta.*?charset=([^"']+)

Должно работать. Использование синтаксического анализатора XML для извлечения этого является перебором.

0 голосов
/ 15 июля 2012

Попробуйте также:

<meta(?!\s*(?:name|value)\s*=)[^>]*?charset\s*=[\s"']*([a-zA-Z0-9-]+)[\s"'\/]*>
0 голосов
/ 09 мая 2012

Это регулярное выражение будет захватывать кодировку значение из любого метатега:

(?<=([<META|<meta])(.*)charset=)([^"'>]*)

Пример ввода:

<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
<meta http-equiv=Content-Type content=text/html; charset=windows-1252>
<meta http-equiv=Content-Type content='text/html; charset=windows-1252'>
<meta http-equiv="Content-type" content="text/html;charset=utf-8" /> 
<meta http-equiv="Content-type" content="text/html;charset=iso-8859-1" /> 

Использовать его следующим образом:

Regex regexObj = new Regex("(?<=<meta(.*)charset=)([^\"'>]*)", RegexOptions.IgnoreCase);
Match matchResults = regexObj.Match(subjectString);
while (matchResults.Success) {
    for (int i = 1; i < matchResults.Groups.Count; i++) {
        Group groupObj = matchResults.Groups[i];
        if (groupObj.Success) {
            // matched text: groupObj.Value
            // match start: groupObj.Index
            // match length: groupObj.Length
        } 
    }
    matchResults = matchResults.NextMatch();
} 

Найдут эти значения:

windows-1252

windows-1252

windows-1252

utf-8

iso-8859-1

0 голосов
/ 11 августа 2010

Мое регулярное выражение:

<meta[^>]*?charset=([^"'>]*)

Мой тестовый набор:

<meta http-equiv="Content-type" content="text/html;charset=utf-8" />
<meta name="author" value="me"><!-- Maybe we should have a charset=something meta element? --><meta charset="utf-8">

C # -код:

using System.Text.RegularExpressions;
string resultString = Regex.Match(sourceString, "<meta[^>]*?charset=([^\"'>]*)").Groups[1].Value;

RegEx-Описание:

// <meta[^>]*?charset=([^"'>]*)
// 
// Match the characters "<meta" literally «<meta»
// Match any character that is not a ">" «[^>]*?»
//    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "charset=" literally «charset=»
// Match the regular expression below and capture its match into backreference number 1 «([^"'>]*)»
//    Match a single character NOT present in the list ""'>" «[^"'>]*»
//       Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
0 голосов
/ 11 августа 2010

Я склонен согласиться с @You, однако я дам вам ответ на ваш запрос, а также некоторые другие решения.

        String meta = "<meta http-equiv=\"Content-type\" content=\"text/html;charset=utf-8\" />";
        String charSet = System.Text.RegularExpressions.Regex.Replace(meta,"<meta.*charset=([^\\s'\"]+).*","$1");

        // if meta tag has attributes encapsulated by double quotes
        String charSet = ((meta.Split(new String[] { "charset=" }, StringSplitOptions.None))[1].Split('"'))[0];
        // if meta tag has attributes encapsulated by single quotes
        String charSet = ((meta.Split(new String[] { "charset=" }, StringSplitOptions.None))[1].Split('\''))[0];

В любом случае любой из вышеперечисленных вариантов должен работать, однако, безусловно, команды String.Split могут быть опасны без предварительной проверки на наличие данных в массиве, поэтому может потребоваться разбить вышеперечисленное, иначе вы получите исключение NullException. 1004 *

0 голосов
/ 11 августа 2010

Для PHP:

$charset = preg_match('/charset=([a-zA-Z0-9-]+)/', $line);
$charset = $charset[1];
0 голосов
/ 11 августа 2010

Не используйте регулярные выражения для разбора (X) HTML ! Используйте подходящий инструмент, то есть синтаксический анализатор SGML или XML. Ваш код выглядит как XHTML, поэтому я бы попробовал парсер XML. Однако после получения атрибута из метаэлемента; регулярное выражение будет более подходящим. Хотя простая строка, разделенная на ;, безусловно, сработает (и тоже быстрее).

0 голосов
/ 11 августа 2010

Я пытался с помощью javascript поместить вашу строку в переменную и сделать совпадение:

var x = '<meta http-equiv="Content-type" content="text/html;charset=utf-8" />';
var result = x.match(/charset=([a-zA-Z0-9-]+)/);
alert(result[1]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...