У меня есть URL (https://example.com?&iframeLoad=true&firstName=&lastName=&email=&phone1=&address=&zipcode=07307&isAvailableReferral=true&isAvailableDirect=false)
Я пытаюсь заменить поля имени, фамилии, электронной почты, телефона и адреса, а не другие.
Это то, что я сейчас делаю, используя регулярное выражение (&? (firstName | lastName | email | phone1 | address) =? [^ &] *)
Это в основном выбирает "&", за которым следует firstName | lastName | email | phone1 | адрес, а также каждый символ после "=". Обратите внимание, что регулярное выражение не соответствует, если за «=» следует символ «&».
Я могу правильно выбрать каждое поле, но когда в URL-адресе есть «&» после «=», мое решение работает некорректно, поскольку оно выбирает только значение до символа «&».
В качестве действующего адреса электронной почты может стоять знак «&». Мне нужно решение, в котором регулярное выражение выбирает, даже если после «=» стоит символ «&».
пример: & email = abc & xyz @ .com - в этом случае регулярное выражение выбирает только «& email = abc &», а не всю электронную почту.
Обычно символ & в URL-адресе будет закодирован в URL-адресе: %26.
В каком языке программирования / программе вы используете регулярное выражение? Поскольку регулярное выражение зависит от платформы, и некоторые механизмы регулярных выражений поддерживают больше функций, чем другие, это очень актуально для вопроса.
Я заменяю строку после сопоставления с помощью javascript. @Graham
Спасибо за вашу помощь! @ Дэвид Фабер и Дэниел



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В зависимости от спецификаций кодировки URL-адреса эту задачу может быть невозможно решить однозначно. Чтобы это было возможно, URL-адреса в наборе данных должны быть стандартизированы таким образом, чтобы каждый параметр имел знак равенства после него, и не должно быть других случайных знаков равенства в значениях параметров.. Если оба этих условия верны, то будет работать следующее:
&(firstName|lastName|email|phone1|address)=([^&]*(?:&[^&=]+(?=&|$))*)
Также обратите внимание, что это регулярное выражение не распространяется на случаи, когда один из требуемых параметров является первым параметром. Поскольку регулярное выражение Javascript ограничено, и в любом случае это особый случай (начиная с ? вместо &), это нужно будет обрабатывать по-разному, в зависимости от того, что вы хотите делать с параметрами. Соответствие следующего и замена на ? - способ удалить параметр:
\?(firstName|lastName|email|phone1|address)=([^&]*(?:&[^&=]+(?=&|$))*)(?:&|$)
Если вы не планируете полностью удалять параметр, для простоты можно удалить (?:&|$) в конце выражения.
В зависимости от того, чем вы планируете заменять параметры, вам может быть полезно настроить выражения, но они, как правило, должны давать желаемый результат в рамках приведенных выше правил.
Хитрость здесь в том, чтобы иметь отдельную группу без захвата (?:&[^&=]+(?=&|$))*, которая обрабатывает дополнительные части строки параметров с необработанными амперсандами, но без знака равенства. Класс символов [^&=]+ гарантирует, что подвыражение не имеет амперсандов или знаков равенства, а опережающий (?=&|$) гарантирует, что за строкой следует другой параметр или конец строки, а не знак равенства. У всей группы есть квантор *, поскольку он может появляться ноль, один или несколько раз после начального параметра.
Также обратите внимание, что для удобства значения имени и значения параметра хранятся в группы захвата 1 и 2 для облегчения доступа и анализа. Если вы не планируете использовать значения, их можно заменить группами без захвата, добавив ?: после (.
Если в каких-либо параметрах отсутствует знак равенства, невозможно однозначно отделить новые параметры URL от значений для предыдущего параметра URL, поскольку в примере https://example.com?&iframeLoad=true&email=abc&[email protected] это может относиться либо к одному параметру с именем email со значением abc&[email protected], либо к двум параметрам. с именами email и [email protected] (если и список строк параметров, и список строк значений не стандартизированы, но на этом пути лежит безумие). Аналогичным образом, случайные знаки равенства обманывают синтаксический анализатор. Как упоминал @David Faber, обычно символ & в URL-адресе будет закодирован как %26, чтобы полностью предотвратить эту двусмысленность.
Благодаря тонну! Это именно то, чего я хотел добиться. Спасибо за подробное объяснение :) @Graham
Вы можете рассмотреть что-то вроде этого:
[&?]((?:firstName|lastName|phone1|address|zipcode)=|email=(?:.*@.*\.)?)[^&]*
Параметр email здесь обрабатывается как особый случай - мы проверяем наличие локальной части, за которой следует субдомен (ы), при этом разрешая TLD без амперсанда (я считаю, что это безопасно - я не думаю, что TLD может содержать нечетные символы как это). Все остальные параметры обрабатываются нормально. Совпадения будут возвращены как пары имя = значение. См. Regex 101 здесь.
Я бы не рекомендовал такой подход. Для начала проверка адреса электронной почты может быть сложной. Даже если вы хотите использовать этот подход, вам следует избегать конструкции .* как из-за эффективности, так и из-за возможные случаи отказа. Этого решения также недостаточно для требования OP о замена текста в URL-адресе: для замены важно знать первый символ, но нет никакого способа узнать его из этого выражения.
Я определенно не предлагаю здесь никакой проверки электронной почты. Я согласен, что .*, вероятно, лучше избегать.
В общем, я думаю, что любой тип проверки электронной почты здесь - плохой подход, потому что он предполагает, что ввод - это законный адрес электронной почты, и мы не можем обязательно предполагать это. Однако, если вы находятся используете (базовый) подход к проверке электронной почты и разрешаете замену, то регулярное выражение, которое вам действительно нужно, было ([&?])((?:firstName|lastName|phone1|address|zipcode)=|email=(?:[^@]*@)?[^&]*). Кроме того, в своем решении я использовал два отдельных регулярных выражения, потому что обработка удаления будет другой для первого параметра.
@ Грэм, спасибо, это лучше, чем мое первоначальное регулярное выражение
рассмотрите возможность использования парсера URL