Помогите составить регулярку для получения "private" переменных
Короче решил немного по-извращаться с кодом. Есть такой код:
(function () { MYAPP.widget = function(oData) { if (oData) { for(var sKey in oData) { this.setData(sKey, oData[sKey]); } } }; MYAPP.widget.prototype = { _oData: {}, getData : function(sField) { if (sField) { return this._oData[sField]; } else { return this._oData; } }, _privateMethod: function () { var text = '_that_dont_get'; }, setData : function(sKey, value) { this._oData[sKey] = value; console.log("this._oData[sKey]"); } } }()) Мне нужно составить регулярное выражение для получения всех переменных и методов, начинающихся с _ , т.е в данном случае это_oData и _privateMethod Составил такую регулярку: (\_[a-zA-Z0-9\_]+) Но она мне помимо нужных мне переменных возвращает и значения, которые находятся в строках. Подскажите как можно безопасно получить только переменные, может есть уже готовые решения? |
Цитата:
|
тред не читал сразу отвечал
obj = {public:11, _private:12}; for (key in obj) if( key.indexOf('_') ) { alert(key) } |
danik.js Спасибо за ответ. Допустим переменные я вытяну, скажите а как мне теперь заменить эти переменные скажем на какое-нибудь другое произвольное имя. Как сделать так, чтобы при замене не попала строка console.log("this._oData[sKey]"); ?
|
var tmp, res = [], re = /(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*')|(\b_\w*)/g; while( tmp = re.exec( s ) ) if( tmp[1] ) res.push( tmp[1] ); |
Цитата:
var re = /(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*')|(\b_\w*)/g; s2 = s.replace( re, function( t1, t2 ) { return t2 ? "new"+t2 : t1 } ); |
rgl Возвращает "'_that_dont_get'" и ""this._dontget1"". Это строки поэтому их не надо
|
Возвращает, но не заменяет, оставляет как было
Первое сообщение было ответом на вопрос "как найти" оно возвращает только то, что требовалось (одной регуляркой, без циклов не получилось). Второе - заменяет, тут обошлось без циклов |
rgl Объясните пожалуйста, что делает первая часть
(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*') |
Как найти что-то, но не найти его, если оно внутри кавычек? Очень просто, нужно сначала найти все, что в кавычках, и тогда оно будет исключено из дальнейшего поиска.
Как найти то, что в кавычках? Найти открывающую кавычку, найти все что угодно, но только не кавычку, найти закрывающую кавычку. В результате получаем "[^"]*" У этого выражения есть один недостаток - оно замаскированную кавычку по ошибке примет за закрывающую. Чтобы этого не произошло, придется его слегка усложнить: "(\\.|[^"])*" - т.е. либо не-кавычка, либо замаскированный любой символ (в т.ч. возможно и кавычка). (Порядок тут важен, сначала замаскированноечтоугодно, а потом - не кавычка, менять нельзя) Чтобы результат в скобочках не "захватывался", добавляем вопрос с двоеточием "(?:\\.|[^"])*" Потом все то же самое повторяем с одинарными кавычками Далее, когда мы нашли нечто, мы нашли либо что-то в кавычках, либо имя переменной, начинающееся с подчерка. Надо отделить одно от другого, проще всего проверить, пустая строка или нет в скобочках (тех, что без вопроса-двоеточия). Вот и все. |
rgl, Спасибо Вам большое за решение, подскажите есть ли еще какие-нибудь подводные камни вроде строк: ?
console.log("this._oData[sKey]");Мне нужно заменить только реальные свойства и методы |
this['_oData'] Это тоже будет заменено или нет? |
Нет это менять не надо, думаю так правильно использовать. Поправьте пожалуйста регулярку :)
|
Цитата:
Цитата:
Мое выражение споткнется, напр. на такой строке: /* this isn't good */ _test = 0; console.log( '_test = 0' ); оно не заменит настоящую переменную, но заменит слово внутри строки. Поэтому для полной уверенности стоит сравнить исходный файл и файл с результатами и убедиться что все замены сделаны правильно. |
Цитата:
var i = '_oData'; // несколько строчек кода this[i]; |
rgl, можем ли с Вам пообщаться в каком-нибудь чате, у меня есть пара вопросов :)
Например: http://learn.javascript.ru/chat мой ник тот же |
Поправлено с учетом возможный комментариев:
var re = /(?:(?:\/\/.*)|(?:\/\*[\s\S]*?\*\/)|"(?:\\.|[^"])*"|'(?:\\.|[^'])*')|(\b_\w*)/g; |
Нет, в чате общаться не получается. А чем форум плох? Много читателей снижают вероятность, что какая-то ошибка останется незамеченной.
|
Цитата:
ЗЫ: вот так у меня сделано в парсере моего шаблонизатора /** * Заметить кавычки с содержимом в строке на ссылку: * __SNAKESKIN_QUOT__номер * * @private * @param {string} str - исходная строка * @param {Array=} [opt_stack] - массив для подстрок * @return {string} */ Snakeskin._escape = function (str, opt_stack) { return str.replace(/(["'])(?:\1|.*?[^\\]\1)/g, function (sstr) { if (opt_stack) { opt_stack.push(sstr); } return '__SNAKESKIN_QUOT__' + (opt_stack ? opt_stack.length - 1 : '_'); }); }; /** * Заметить __SNAKESKIN_QUOT__номер в строке на реальное содержимое * * @private * @param {string} str - исходная строка * @param {!Array} stack - массив c подстроками * @return {string} */ Snakeskin._uescape = function (str, stack) { return str.replace(/__SNAKESKIN_QUOT__(\d+)/g, function (sstr, pos) { return stack[pos]; }); }; |
Цитата:
var s = "abcd\\"; |
Цитата:
(["'])(?:\1|.*?(?:[\\]{2}|[^\\])\1) |
kobezzza,
Цитата:
Мой вариант: (["'])(?:\\.|(?:(?!\1).)*\1) |
Цитата:
var a = '\a':у тебя упадёт, из-за странной проверки \\. var a= 'sdsd\'также упадёт |
Не, ну как только я начинаю проверять регэкспы, рискую нарваться :-)
a='aaa\\\'a';b='bbb'; Цитата:
Цитата:
(["'])(?:\\.|(?:(?:(?!\1).)))*\1 |
Цитата:
А насчет var a= 'sdsd\' так я предполагаю, что JS-ных ошибок нет, т.е. все кавычки в строке закрываются |
var a= '\\\' :)
UPD: не прочитал, что ты не учитываешь этот фактор, тада всё ок. |
Цитата:
Раз уж устроили тут такое соревнование-блиц, нужно договориться о правилах, напр, допустимы ли непарные кавычки в строчке. Я изначально считал, что применяться регэксп будет к JavaScript коду, в котором нет ошибок (так тема начиналась), а значит кавычки должны обязательно закрываться. |
Цитата:
|
Вот при корректном JavaScript кода мой работает правильно, а твой ошибается:
var a= 'a\\\'a'; |
Цитата:
/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')/ но тут одинарная и двойная кавычки каждая сама по себе, а тебе хочется чтобы вместе. |
Кажется, добил таки:
(["'])(?:\\.|(?:(?:(?!\1|\\).)))*\1 Уф-ф-ф, хорошо поразминался, а то уже подзабывать начал :-) |
Убрал лишние скобки:
(["'])(?:\\.|(?:(?!\1|\\).))*\1 |
Цитата:
Цитата:
|
Цитата:
вот я вырезал регу со своего скрипта: https://github.com/devote/QSA/blob/master/qsa.js var re = /(?:(['"])\1|(['"])(?:\\\\|[\s\S])*?(?:\\\\(?=\2)|[^\\])\2)/g; var testText = 'привет "МИР"! тут я поставлю кавычку " а можно и слеши \\ или кавычка со слешами \\\" или кавычки " " или много слешей и ковычка \\\\\\\\\\\\\\\\" и" т.\\\\\\\\\\\\\\\\\\"д"......'; alert(testText.match(re).join("\n")); // выведет четыре подстроки // ищем в коде все строки: var code = "// for Internet Explorer VisualBasic Script accessors\ if (type !== 3) {\ // create getter in VB Class\ staticClassParts.push(\ 'Public ' + (type === 4 ? 'Default ' : '' ) + 'Property Get [' + subName + ']',\ 'Call VBCorrectVal(' + ( value && ( type !== 1 || value.get) ?\ '[(accessors)].[' + prop + ']' + (type === 1 ? '.get' : '') +\ '.call(me,[(accessors)].[' + prop + '])' : 'window.undefined' ) +\ ',[' + subName + '])', 'End Property'\ );\ }\ if (type !== 2) {\ // create setter in VB Class\ staticClassParts.push(\ 'Public Property Let [' + subName + '](val)',\ type = (type === 4 ? 'Set [(accessors)].[' + prop + ']=val' :\ value && (type !== 1 || value.set) ?\ 'Call [(accessors)].[' + prop + ']' + (type === 1 ? '.set' : '') +\ '.call(me,val,[(accessors)].[' + prop + '])' : '') +\ '\nEnd Property', 'Public Property Set [' + subName + '](val)', type\ );\ }"; alert(code.match(re).join("\n")); // выведет все найденные строки Пользовательский тест: var re = /(?:(['"])\1|(['"])(?:\\\\|[\s\S])*?(?:\\\\(?=\2)|[^\\])\2)/g; var str = prompt('Введите строку') || ''; var res = str.match(re); alert("Найдено: " + (res&&res.length||0) + " вхождени(е/й/я)\n--------------------------\n" + (res||[]).join("\n")); Если нужно парсить код, то для начала, нужно удалить из кода все комменты, а потом искать строки.. Ну и про регулярки не забывать, в них тоже кавычки могут встретится: <textarea id="area" style="width: 860px; height: 130px;" placeholder="вставь сюда JavaScript код и нажми кнопку process"></textarea> <button onclick="process()">process</button> <script> function process() { var rRemoveCommentsAndRexExp = /((['"])\2|(['"])(?:\\\\|[\s\S])*?(?:\\\\(?=\3)|[^\\])\3)|\/\*[\S\s]*?\*\/|\/[^\/](?:\\\\|[\s\S])*?(?:\\\\(?=\/)|[^\\])\/|\/\/[^\n]*/g; var rSearchStrings = /(?:(['"])\1|(['"])(?:\\\\|[\s\S])*?(?:\\\\(?=\2)|[^\\])\2)/g; var value = document.getElementById('area').value; var str = value.replace(rRemoveCommentsAndRexExp, '$1'); var res = str.match(rSearchStrings); alert("Найдено: " + (res&&res.length||0) + " вхождени(е/й/я)\n--------------------------\n" + (res||[]).join("\n")); } </script> |
поправил выше код, со слешами не правильно работала рега. Терь гуд
|
Цитата:
|
Цитата:
Цитата:
|
Что не так??
var testText = 'привет "МИР"! тут я поставлю кавычку " а можно и слеши \\ или кавычка со слешами \\\" или кавычки " " или много слешей и ковычка \\\\\\\\\\\\\\\\" и" т.\\\\\\\\\\\\\\\\\\"д"......'; var re = /(["'])(?:\\.|(?:(?!\1|\\).))*\1/g; alert( testText.match(re).join("\n") ); |
Цитата:
var str = 'привет "МИР"! тут я поставлю кавычку " а можно и\n слеши \\ или кавычка со слешами \\" или кавычки " " или много\n слешей и ковычка \\\\\\\\\\\\\\\\" и" т.\\\\\\\\\\\\\\\\\\"д"......'; var re = /(["'])(?:\\.|(?:(?!\1|\\).))*\1/g; var res = str.match(re); alert("Найдено: " + (res&&res.length||0) + " вхождени(е/й/я)\n--------------------------\n" + (res||[]).join("\n")); // ---------- var re = /(?:(['"])\1|(['"])(?:\\\\|[\s\S])*?(?:\\\\(?=\2)|[^\\])\2)/g; var res = str.match(re); alert("Найдено: " + (res&&res.length||0) + " вхождени(е/й/я)\n--------------------------\n" + (res||[]).join("\n")); |
А вот ваша рега как раз ошибается, находит там, где находить не должна (ошибочно замаскированную кавычку принимает за закрывающую):
var testText = "a'b\\\\\\'c" var re = /(?:(['"])\1|(['"])(?:\\\\|[\s\S])*?(?:\\\\(?=\2)|[^\\])\2)/g; alert( testText.match(re).join("\n") ); |
Часовой пояс GMT +3, время: 06:47. |