Регулярные выражения — ликбез по регэкспам
Posted: Mon 20 Feb, 2006 00:41
Очень хотелось бы больше примеров по регэкспам в документации, т.к. впервые столкнувшись с серьёзной задачей, разобраться очень трудно. Сколько ни бился, так и не получилось такое вот: имеется много html\xml файлов, в них теги прописаны большими, маленькими буквами и смешаным регистром. У тегов естессно, есть параметры, причём в виде: параметр=значение, параметр="значение", параметр='значение'. Требуется привести теги и их параметры, не имеющие смешаного регистра, к \l, при этом ни в коем случае не менять регистр значений. Более того, все значения нужно взять в кавычки.
Т.е. <A HREF=http://www.some.com/REG.HTML>...</A> нужно перевести в <a href="http://www.some.com/REG.HTML">...</a>
<SomeTag SomeParam=SomeValue /> перевести <SomeTag SomeParam="SomeValue" />,
а, допустим <meta http-equiv="Content-Type" content=text/html; charset=windows-1251> в <meta http-equiv="Content-Type" content="text/html;" charset="windows-1251">
Задача номер следующая: теги, не имеющие закрывающую пару, и не закрывающиеся сами - закрыть. Т.е. те же <meta http-equiv="Content-Type" content="text/html;" charset="windows-1251"> перевести в <meta http-equiv="Content-Type" content="text/html;" charset="windows-1251" />
<img src="..."> в <img src="..." />
Я так понимаю, что задача выполнимая. Но как это сделать? По существующей документации разобраться очень трудно.
<img src="..."> - это если (<.*?\s)(.*?(?<![\/|\/\s])>) и как-то обозначить, что дальше по тексту не встречается $1.*?(?<=[\/|\/\s])> - как-то так...
То тогда менять на $1...[внутренности тега]... /> Во всяком случае такая строка поиска находит теги, не закрывающие сами себя... И в то же время такие вот вещи "<b> some </b>some<b>" (оказывается выделенным всё, что в кавычках). Но как дальше? И как избежать вот этих ошибок. Нужно как-то обозначить, что внутри $1 не должно быть ">" и вообще та закрывающая скобка, которая явно нарисована, должна быть первой закрывающей.
Да, ещё, нужно учесть, что закрывающий тег может быть и не в той же самой строке. А в сложных случаях - вложенность тегов...
И ещё, можно ли как-то указать, что группа должна быть больше, меньше, равно, не больше, не меньше, чем столько-то символов? Не считая, конечно, явного составления из "ровно один любой символ". Могу я для строки AZXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX указав A.*X, указать ещё и длину не больше 15 символов? Хотя здесь ещё просто, а вот для предыдущих упражнений с тегами задавать длину не более 75 символов со всеми параметрами?
Как можно задать строку-исключение? "XXX" не должна входить в "A.*?Z".
Думаю, если подробный разбор этого дела сделать (с пояснениями), то практически с любой степенью сложности регэкспов можно будет справиться. Или есть и более сложные примеры?
(<(?!\/).+?\s(?<!>))(.*?(?<![\/|\/\s])>) находит "<b> some </b>", но не "<b> some </b>some<b>" (без кавычек).
А ещё "<pre><font size=4>".
(<(?!\/).+?[\s>](?<!>))(.*?(?<![\/|\/\s])>) и того хуже.
Т.е. <A HREF=http://www.some.com/REG.HTML>...</A> нужно перевести в <a href="http://www.some.com/REG.HTML">...</a>
<SomeTag SomeParam=SomeValue /> перевести <SomeTag SomeParam="SomeValue" />,
а, допустим <meta http-equiv="Content-Type" content=text/html; charset=windows-1251> в <meta http-equiv="Content-Type" content="text/html;" charset="windows-1251">
Задача номер следующая: теги, не имеющие закрывающую пару, и не закрывающиеся сами - закрыть. Т.е. те же <meta http-equiv="Content-Type" content="text/html;" charset="windows-1251"> перевести в <meta http-equiv="Content-Type" content="text/html;" charset="windows-1251" />
<img src="..."> в <img src="..." />
Я так понимаю, что задача выполнимая. Но как это сделать? По существующей документации разобраться очень трудно.
<img src="..."> - это если (<.*?\s)(.*?(?<![\/|\/\s])>) и как-то обозначить, что дальше по тексту не встречается $1.*?(?<=[\/|\/\s])> - как-то так...
То тогда менять на $1...[внутренности тега]... /> Во всяком случае такая строка поиска находит теги, не закрывающие сами себя... И в то же время такие вот вещи "<b> some </b>some<b>" (оказывается выделенным всё, что в кавычках). Но как дальше? И как избежать вот этих ошибок. Нужно как-то обозначить, что внутри $1 не должно быть ">" и вообще та закрывающая скобка, которая явно нарисована, должна быть первой закрывающей.
Да, ещё, нужно учесть, что закрывающий тег может быть и не в той же самой строке. А в сложных случаях - вложенность тегов...
И ещё, можно ли как-то указать, что группа должна быть больше, меньше, равно, не больше, не меньше, чем столько-то символов? Не считая, конечно, явного составления из "ровно один любой символ". Могу я для строки AZXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX указав A.*X, указать ещё и длину не больше 15 символов? Хотя здесь ещё просто, а вот для предыдущих упражнений с тегами задавать длину не более 75 символов со всеми параметрами?
Как можно задать строку-исключение? "XXX" не должна входить в "A.*?Z".
Думаю, если подробный разбор этого дела сделать (с пояснениями), то практически с любой степенью сложности регэкспов можно будет справиться. Или есть и более сложные примеры?
(<(?!\/).+?\s(?<!>))(.*?(?<![\/|\/\s])>) находит "<b> some </b>", но не "<b> some </b>some<b>" (без кавычек).
А ещё "<pre><font size=4>".
(<(?!\/).+?[\s>](?<!>))(.*?(?<![\/|\/\s])>) и того хуже.