Помогите с регулярным выражением JavaScript, чтобы добавить обратную косую черту для определенных символов, если еще не существует - PullRequest
2 голосов
/ 02 марта 2011

У меня есть еще одна загадка Javascript regex ... (извините, если это немного запутанно - трудно объяснить!)

У меня есть скрипт, который отправляет строку во всплывающее окно (все символызакодированы, когда они отправлены, поэтому все обратные слеши сохраняются).Во всплывающем окне имеется несколько текстовых полей ввода, а также «сводный» диапазон, который отображает то, что находится во всех полях ввода, и обновляется всякий раз, когда обнаруживается keyup.Затем, когда пользователь завершает работу, он нажимает кнопку, которая отправляет обновленную итоговую строку обратно в средство открытия.

Требуется, чтобы обратная косая черта автоматически добавлялась к следующим символам: \ / }, поэтому пользователь не 'Не нужно делать это самим.В настоящее время у меня есть код, который удаляет все обратные слеши в полях ввода, но в сводке они добавляются в соответствующих случаях.

Например.если эта строка отправляется во всплывающее окно: foobar\\batz\/hi, то в сводке она будет выглядеть следующим образом: foobar\\batz\/hi и в поле ввода будет выглядеть так: foobar\batz/hi.Если вы затем отредактируете строку, подобную этой, в поле ввода: foobar\batz/hiya, то в сводке она будет выглядеть следующим образом: foobar\\batz\/hiya.Пока все хорошо ... но если вы попытаетесь ввести это в поле ввода: foobar\\batz/hiya, то в сводке это будет выглядеть так: foobar\\\batz\/hiya.Это должно выглядеть так: foobar\\\\batz\/hiya

Это относится к существующему коду (который запускается на каждом 'kepup').По сути, для просмотра строки требуется регулярное выражение и добавление обратной косой черты к \ / or }, если они еще не существуют.Это требует отрицательного взгляда за спиной, чтобы проверить наличие существующих обратных косых черт (но javascript не может делать отрицательные взгляды сзади).Я подумал, что взломал это, сначала перевернув строку (используя пользовательскую функцию) и выполнив отрицательный просмотр, затем снова перевернув строку, как показано ниже:

var thisBoxVal = $(this).val();
thisBoxVal = reverseStr(thisBoxVal);
thisBoxVal = thisBoxVal.replace(/(\}|\/|\\(?!\\))/g,"$1\\");
thisBoxVal = reverseStr(thisBoxVal);

Однако теперь я вижу, гдепроблема лежит.При обнаружении первого (или второго, потому что он обратный) двойного обратного слэша, он добавляет дополнительный обратный слеш.Но поскольку у 2-го обратного слэша уже есть этот первый обратный слеш, он не будет его добавлять.

У меня также есть проблемы с выделением памяти каждый раз, когда строка переворачивается.Это потому, что я узнал, что строки javascript являются неизменяемыми, что, как мне кажется, приводит к неудачному распределению дополнительной памяти при каждом обращении строки.Выполнение этого при каждом нажатии клавиши (поскольку это необходимо для обновления строки сводки при каждом изменении поля ввода) может вызвать некоторые проблемы (...?).

Есть ли другой способ сделать это?Предпочтительно только с некоторым регулярным выражением и без обратного ...

Итак, подведем итог: необходимо создать замену регулярного выражения, которая ищет строку для любого из этих символов \ / } и добавить обратную косую черту перед запуском.их (если экранирующий слеш еще не существует).Таким образом, он должен обладать интеллектом, когда сталкивается с более чем одним обратным слешем подряд, чтобы избежать каждого из них (обратите внимание, что я обновляю не фактическое поле ввода, а переменную, которую я использую для обновления сводки).

Мне нужна помощь мастера регулярных выражений!

Ответы [ 3 ]

2 голосов
/ 02 марта 2011

Вы можете экранировать все, что не букву, цифру, пробел или обратную косую черту.

string=string.replace(/([^\w \\])/g,'\\$1')
1 голос
/ 02 марта 2011

Вы можете проверить наличие экранированных символов обратной косой черты, проверив четное число обратной косой черты перед символами, которые нужно экранировать, и в этом случае требуется дополнительная обратная косая черта:

thisBoxVal = thisBoxVal.replace(/(^|[^\\])((?:\\{2})*)(\\(?=[^\\/}]|$)|[/}])/g, '$1$2\\$3');

Регулярное выражение разбивается следующим образом:

  • (^|[^\\]): перед экранированием сопоставьте что-то, что не является экранированием (начало строки или не - \)
  • ((?:\\{2})*): четное число escape-символов. В каждой паре первое избегает второго, поэтому мы не хотим их трогать.
  • (\\(?=[^\\/}]|$)|[/}]): убегающий персонаж:
    • \\(?=[^\\/}]|$): обратная косая черта, за которой следует что-то, что не является экранируемым, то есть либо символ, который не является экранируемым ([^\\/}], в противном случае этот обратный слеш сам по себе должен был бы экранировать следующий за ним символ), либо конец из-строки.
    • [/}]: экранируемый символ, отличный от обратной косой черты.

Пример строки:

thisBoxVal = "sl0: \\;  sl1: /;  sl2: \\\\\\;  nosl0: \\\\;  nosl1: \\{;  sl3: \\";

Значение печати: "sl0: \; sl1: /; sl2: \\\; nosl0: \\; nosl1: \{; sl3: \"
Результат replace: "sl0: \\; sl1: \/; sl2: \\\\; nosl0: \\; nosl1: \{; sl3: \\"

1 голос
/ 02 марта 2011

Следующее должно решить это:

thisBoxVal = thisBoxVal.replace/((\}|\/(?!\\))|\\)/g,"$1\\");

Но требование кажется странным. Почему \\ переводится в \\\\, а \{ в \{. Это также означает, что если строка foo\\{bar находится в сводке, она равна foo\{bar в поле ввода, и при повторном сохранении она становится foo\{bar в сводке. Это звучит как ошибка. Если бы я был тобой, я бы вообще отбросил негативный взгляд ..

...