2013-02-14 23 views
6

У меня есть многословная строка регулярного выражения python (с большим количеством пробелов и комментариев), которые я бы хотел преобразовать в «обычный» стиль (для экспорта в javascript). В частности, мне нужно, чтобы это было достаточно надежным. Если есть какой-то явно правильный способ сделать это, я хочу этого. Например, наивная реализация уничтожит регулярное выражение, например r' \# # A literal hash character', что не совсем нормально.strip verbose regex python

Лучший способ сделать это - принудить модуль python re, чтобы вернуть мне нерегулярное представление моего регулярного выражения, но я не вижу способа сделать это.

+2

Видимо кто-то сделал это, но это в JavaScript http://blog.mackerron.com/2010/08/08/extended-multi-line-js-regexps/ –

+0

К сожалению, он преобразует настраиваемый подробный синтаксис регулярных выражений в синтаксис JS regex, что не совсем то же самое, что преобразование синтаксиса регулярного выражения Python verbose в синтаксис регулярного выражения Python без вербовки ... но вы можете определенно использовать этот код в качестве модели для написания собственного эквивалента Python, если вы не можете найти его. – abarnert

+0

Это не должно быть слишком сложно. Просто удалите перед \ n, но до #, и удалите все, что соответствует \ w, но не \\\ w. – Linuxios

ответ

4

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

  1. удалять комментарии до конца строки
  2. удалить неэкранированный пробельные

попробовать это, какие сети 2 с отдельными регулярными выражениями:

import re 

def unverbosify_regex_simple(verbose): 
    WS_RX = r'(?<!\\)((\\{2})*)\s+' 
    CM_RX = r'(?<!\\)((\\{2})*)#.*$(?m)' 

    return re.sub(WS_RX, "\\1", re.sub(CM_RX, "\\1", verbose)) 

Вышеприведенное упрощение d, которая оставляет экранированные пробелы как есть. Полученный результат будет немного сложнее читать, но должен работать на платформах regex.

В качестве альтернативы, для чуть более сложного ответа, что «декодирует» пространство (т.е. «\» => ' «) и возвращает то, что я думаю, что большинство людей были бы ожидать:

import re 

def unverbosify_regex(verbose): 
    CM1_RX = r'(?<!\\)((\\{2})*)#.*$(?m)' 
    CM2_RX = r'(\\)?((\\{2})*)(#)' 
    WS_RX = r'(\\)?((\\{2})*)(\s)\s*' 

    def strip_escapes(match): 
     ## if even slashes: delete space and retain slashes 
     if (match.group(1) is None): 
     return match.group(2) 

     ## if number of slashes is odd: delete slash and keep space (or 'comment') 
     elif (match.group(1) == '\\'): 
     return match.group(2) + match.group(4) 

     ## error 
     else: 
     raise Exception 

    not_verbose_regex = re.sub(WS_RX, strip_escapes, 
         re.sub(CM2_RX, strip_escapes, 
         re.sub(CM1_RX, "\\1", 
          verbose))) 

    return not_verbose_regex 

UPDATE: добавил комментарии, чтобы объяснить даже v. подсчет нечетной косой черты. Исправлена ​​первая группа в CM_RX, чтобы сохранить полный «комментарий», если количество слэшей нечетное.

ОБНОВЛЕНИЕ 2: Исправлены комментарии regex, которые не имели отношения к экранированным хэшам должным образом. Если обрабатывать как «\ # #escaped хэш», а также «# комментарий с \ # спасся хэш» и «\\ # комментарий»

UPDATE 3: Добавлена ​​упрощенная версия, которая не очищает сбежавших пространства ,

UPDATE 4: Дальнейшее упрощение для устранения переменной длины отрицательного просмотра назад (и в обратном направлении/обратный прием)

+0

Чтобы улучшить ваш ответ, вы также можете преобразовать '' \ ''в' ''', ''\ #'' в '' # ''. – Ray

+0

Пункт 2 должен быть изменен, чтобы заявить, «за исключением случаев, когда это происходит в наборах», что делает реализацию намного сложнее. – user4815162342

+0

Спасибо - ответ обновлен, чтобы освободить пространства и хэши. – dpkp