Dreamweaver Regex - Unmatched) в регулярном выражении

671
MrMarlow

Проблема

Проблема, с которой я сталкиваюсь, заключается в том, что в прошлом разработчики некоторого кода, над которым я работаю, устанавливают переменные, такие как $ _GET [name] или иногда как $ _GET ['name']. Пытаясь сделать код единообразным, я хочу, чтобы все они были похожи на $ _GET ['name']

Попытка решения

В пользовательском скрипте DreamWeaver я использовал следующее.

dreamweaver.setUpFindReplace({ searchString: "\$(_POST|_SESSION|_GET)\[([^\'][0-9a-zA-Z _]+?[^\'])\]", replaceString: "$$1['$2']", searchWhat: "document", searchSource: true, useRegularExpressions: true }); dreamweaver.replaceAll(); 

Дополнительная информация

Когда я получаю сообщение об ошибке при запуске его из пользовательского сценария, я не получаю его при запуске тех же строк "searchString" и "replaceString" в строке поиска (CTRL + F).

Подсказка поиска с радостью найдет и заменит случаи, когда это происходит.

Прежде чем кто-то потенциально укажет на этот факт - да, я мог бы просто запустить «Поиск приглашения» и сделать это оттуда, но мне все еще нужно запустить собственный сценарий, чтобы запустить остальные 20 или около того параметров поиска и замены.

У вас есть пример конечных результатов где-нибудь?

Конечно да. У меня есть регулярное выражение, используемое на Regex 101 - https://regex101.com/r/bE9kN6/1

В заключение...

Кто-нибудь знает, как остановить проблему непревзойденных скобок? Я пытался какое-то время, и я не могу найти решение, так как нет непревзойденных скобок.

Решение

Спасибо Бобу за выяснение этого. Dreamweaver использует JS regex (который, как я не думал, отличается от PHP, но оказывается, что POSIX - один, а perl-regex [или что-то в этом роде ...]), и литералы нужно экранировать с помощью \\not \.

Это сделало окончательную, рабочую функцию;

dreamweaver.setUpFindReplace({ searchString: "\\$(_POST|_SESSION|_GET)\\[([^\'][0-9a-zA-Z _]+?[^\'])\\]", replaceString: "$$1['$2']", searchWhat: "document", searchSource: true, useRegularExpressions: true }); dreamweaver.replaceAll(); 
2
Я не вижу никакой ошибки (как и Regex101), и я пришел к выводу, что вы нашли ошибку в DreamWeaver. Я не думаю, что одиночная кавычка будет иметь какое-то особое значение в параметре `searchString`, поэтому вы можете попробовать ее без предшествующей обратной косой черты и посмотреть, работает ли она вокруг нее. Если нет, попробуйте упростить второе помеченное выражение, пока не потеряете ошибку: она не будет делать то, что вы хотите, но пока это не имеет значения. AFH 8 лет назад 0
Спасибо за ответ AFH. Просто взялся за работу и перед компьютером, так что попробую сейчас - я скоро вернусь сюда. MrMarlow 8 лет назад 0
Это было бы отрицательно - удаление обратно до `\ $ (_ POST | _SESSION | _GET) \ [` дает «Неопределенный символьный класс», но работает на regex101 - и делает поиск жадным, используя `\ $ (_ POST | _SESSION | _GET) \ [(. +?) \] `Не заменяется параметром ReplaceWith. Начинает не любить DW Regex. MrMarlow 8 лет назад 0
Дальнейшее тестирование - даже `searchString:" \ $ (_ POST | _SESSION | _GET) ", replaceString:" \ $ _ GET ",` не заменяет $ _POST и $ _SESSION на $ _GET. MrMarlow 8 лет назад 0
@SlackBadger Вы пытались избежать обратной косой черты? Я не использовал DreamWeaver, но он очень похож на JS и в строковом литерале JS `" \ ["` становится `[`, где вы, вероятно, хотите, чтобы `" \\ ["` стал `\ [`. Попробуйте использовать двойную обратную косую черту в строковом литерале везде, где вы хотите обратную косую черту в действительном регулярном выражении. Bob 8 лет назад 0
Боб, я люблю тебя прямо сейчас. Вы были правы, это JS Regex, и это действительно решило проблему. Если вы могли бы бросить это в ответ - вы можете взять принятый ответ и награду в 100 баллов :) MrMarlow 8 лет назад 0
Рад слышать! Я напишу правильный ответ, когда вернусь домой. Мобильный набор текста отстой. Bob 8 лет назад 0

1 ответ на вопрос

1
Bob

Ваше побег немного сбит. Похоже, вы используете JavaScript, а строковый литерал "\$(_POST|_SESSION|_GET)\[([^\'][0-9a-zA-Z _]+?[^\'])\]"оценивается как $(_POST|_SESSION|_GET)[([^'][0-9a-zA-Z _]+?[^'])].

Вместо этого вы должны использовать "\\$(_POST|_SESSION|_GET)\\[([^'][0-9a-zA-Z _]+?[^'])\\]", который оценивает \$(_POST|_SESSION|_GET)\[([^'][0-9a-zA-Z _]+?[^'])\].


Причина в том, что на самом деле у вас есть два уровня синтаксического анализа, каждый со своими собственными правилами экранирования. Во-первых, у вас есть строковый литерал JavaScript, который позволяет экранировать такие вещи, как \nдля новой строки. Тем не менее, нераспознанные escape-последовательности, такие "\["как "молча" проглатываются и производят [. Движок регулярных выражений видит [, указывая начало класса персонажа.

Вы хотите, чтобы механизм регулярных выражений получал буквальные обратные слеши в шаблоне. Для этого вы должны сначала создать строку JS, содержащую буквенные обратные косые черты. Это означает, что вы должны избегать обратной косой черты в строковом литерале, поэтому "\\"производит \, например, "\\["производит строку \[. Таким образом, механизм регулярных выражений видит \[, указывая на экранированную (буквальную) скобку.

Другое дело, что одиночные кавычки вообще не нужно экранировать, поскольку они не имеют специального значения в регулярном выражении, а одиночные кавычки внутри строки в двойных кавычках обрабатываются JS как обычные символы.


Есть еще один вариант, но я не уверен, что DreamWeaver его примет. JavaScript имеет специальный синтаксис регулярных выражений, поэтому вам не нужно сначала создавать строку. Пропустив этот дополнительный шаг разбора, вы фактически избегаете необходимости двойного выхода. Литерал регулярного выражения JS имеет форму /pattern/options(косые черты необходимо экранировать, но в этом шаблоне их нет). Таким образом, ваш шаблон может быть выражен как /\$(_POST|_SESSION|_GET)\[([^'][0-9a-zA-Z _]+?[^'])\]/. Еще раз, одинарные кавычки не нужно вообще избегать.

Если DreamWeaver поддерживает литеральный синтаксис regex, это на самом деле предпочтительный вариант.

«Вы можете наградить свою награду за 21 час» - я дам это утром :) MrMarlow 8 лет назад 0
Хорошо заметили - я полностью пропустил это. AFH 8 лет назад 0
Сейчас я выбрал лучший ответ - я бы тоже проголосовал за тебя, но, видимо, мне нужно 15 репутаций за это, а отдать 100 означает, что я сейчас в 13 - плохие времена! MrMarlow 8 лет назад 0

Похожие вопросы