Привет, ребята, я новичок в регулярных выражениях, вы можете мне с этим помочь.
У меня есть строка вроде этой "<input attribute='value' >", где attribute='value' может быть чем угодно, и я хочу сделать preg_replace, чтобы получить только <input />.
Как указать подстановочный знак для замены любого количества любых символов в srting?
нравится? preg_replace("/<input.*>/",$replacement,$string);
Большое спасибо






Что у тебя есть:
.*
будет соответствовать "любому персонажу и как можно большему количеству символов".
что ты такое иметь в виду
[^>]+
что переводится как "любой символ, это не"> ", и должен быть хотя бы один
или альтернативно,
.*?
что значит "любой персонаж, но ровно столько, чтобы это правило работало"
Разбор HTML с помощью регулярных выражений - Плохой
использовать любой из существующих парсеров html, библиотек DOM, что угодно, ТОЛЬКО НЕ НАИВНЫЙ РЕГЕКС
Например:
<foo attr = ">">
Будет ошибочно захвачен регулярным выражением как
'<foo attr = " ' with following text of '">'
Что приведет вас к этому регулярному выражению:
`<[a-zA-Z]+( [a-zA-Z]+=['"][^"']['"])*)> etc etc
в этот момент вы обнаружите этот прекрасный драгоценный камень:
<foo attr = "'>\'\"">
и твоя голова взорвется.
(Подсветка синтаксиса подтверждает мою точку зрения и неверно совпадает с мнением, что я закончил тег.)
@John: да, я знаю, но эти парни явно зеленые в этих условиях;)
Вы были правы в части взрыва головы ... говоря по опыту.
Как вы можете подумать, что такое чудовище, как "<foo attr = '>'>", было даже возможный в HTML? Я знаю, что вы говорите о XSS, но я полагаю, что мы не рассматриваем вопрос «Как очистить неправильный ввод пользователя?» вопрос здесь. Само по себе разрешение пользователям вводить HTML - это большая проблема.
preg_replace("<input[^>]*>", $replacement, $string);
// [^>] means "any character except the greater than symbol / right tag bracket"
Это действительно материал базовый, вам стоит наверстать упущенное с чтением. :-)
Это почти работает, но не работает с атрибутами, в значении которых есть '>', например. <input attr = "3> 2">.
@Adam: это точно, почему вы не должны использовать Regex для синтаксического анализа html.
Как ни странно, похоже, что разрешение> в значениях атрибутов было сделано только для того, чтобы указать против использования регулярных выражений в HTML (я никогда не видел, чтобы это использовалось в реальной жизни). Но это хороший момент.
@PHiLho, надеюсь, не используется в реальной жизни, но это один из способов, которыми люди создают код для целей XSS. И это быстро становится уродливым.
К сожалению, в значениях атрибутов нет символов '>'. Никогда. Если есть в ваш HTML, перед вами совершенно другая проблема.
Я бы не сказал, что это базовый, каким бы то ни было образом. Убедиться, что вы правильно сопоставляете HTML, довольно сложно, особенно когда вы начинаете пытаться сопоставить вложенные теги.
Он ничего не сказал о вложенных тегах. Его вопрос был довольно прямым, и регулярное выражение, которое делает то, что он хочет, действительно является базовое.
Вы правы - символ '>' внутри атрибутов недействителен, но самый популярный браузер может правильно его проанализировать в большинстве случаев (если значение атрибута указано правильно). Пример реального кода с '>' внутри значения атрибута: <input ... onkeypress = "if (this.length> 10) return false;">
Некоторые были близки ... но не на 100%:
Этот:
preg_replace("<input[^>]*>", $replacement, $string);
должно быть это:
preg_replace("<input[^>]*?>", $replacement, $string);
Вы же не хотите, чтобы это был жадный матч.
Жадность здесь не имеет значения, поскольку использование [^>] * вместо. * Приведет к тому, что он будет соответствовать всем не-> символам до тех пор, пока не будет найден>, и самые длинные (жадные) и самые короткие (не жадные) прогоны не- > символы, за которыми следует>, будут идентичны во всех случаях.
Если я правильно понял вопрос, у вас есть код:
preg_replace("/<input.*>/",$replacement,$string);
и вы хотите, чтобы мы сказали вам, что вы должны использовать для замены $, чтобы удалить то, что было найдено. *
Вы должны сделать это наоборот. Используйте группы захвата, чтобы захватить то, что вы хотите сохранить, и повторно вставьте это в замену. Например.:
preg_replace("/(<input).*(>)/","$1$2",$string);
Конечно, вам действительно не нужно собирать группы здесь, так как вы повторно вставляете только буквальный текст. Спорим, выше показан метод, если вы хотите сделать это в ситуации, когда теги могут отличаться. Это лучшее решение:
preg_replace("/<input [^>]*>/","<input />",$string);
Класс инвертированных символов более конкретен, чем точка. Это регулярное выражение будет работать, если в строке есть два тега HTML. Ваше исходное регулярное выражение не будет.
Концепция «как можно больше» против «ровно столько» в большей части документации называется «жадностью».