регулярное выражение для сопоставления postgresql bytea - PullRequest
2 голосов
/ 01 марта 2010

В PostgreSQL есть тип данных BLOB, называемый bytea. Это просто массив байтов.

Литералы bytea выводятся следующим образом:

'\\037\\213\\010\\010\\005`Us\\000\\0001.fp3\'\\223\\222%'

См. Документы PostgreSQL для полного определения формата.

Я пытаюсь создать регулярное выражение Perl , которое будет соответствовать любой такой строке.
Он также должен соответствовать стандартным строковым литералам ANSI SQL, таким как 'Joe', 'Joe''s Mom', 'Fish Called ''Wendy'''
Он также должен соответствовать варианту с обратной косой чертой: 'Joe\'s Mom',.

Первый подход (показанный ниже) работает только для некоторых представлений байтов.

s{ '               # Opening apostrophe
    (?:            # Start group
        [^\\\']    #   Anything but a backslash or an apostrophe
    |              #  or
        \\ .       #   Backslash and anything
    |              #  or
        \'\'       #   Double apostrophe
    )*             # End of group
  '                # Closing apostrophe
}{LITERAL_REPLACED}xgo;

Для других (более длинных, со многими избежавшими апострофами, Perl выдает следующее предупреждение:

Превышен комплексный предел рекурсии регулярного подвыражения (32766) в строке ./sqa.pl, <> строка 1.

Так что я ищу лучшее (но все еще основанное на регулярных выражениях) решение, оно, вероятно, требует некоторой алхимии регулярных выражений (избегая обратных ссылок и всего).

Ответы [ 3 ]

1 голос
/ 01 марта 2010

Хорошо, вот лучшее решение, которое я смог собрать, благодаря Леону и Хоббсу.

Примечание: это не то решение, которое я искал! Это все еще приводит к сбою Perl с предупреждением «превышен предел рекурсии (32766)» для некоторых длинных строк. (попробуйте добавить 400 тыс. случайных байтов в поле байтов, затем экспортируйте с помощью pg_dump --inserts).

Однако он соответствует большинству байтовых строк (как они появляются в коде SQL и в журналах сервера) и строковым литералам SQL ANSI. Например:

'\014cS\0059\036a4JEd\021o\005t\0015K7'
'\\037\\213\\010\\010\\005`Us\\000\\0001.fp3\'\\223\\222%'
' Joe''s Mom friend\'s dog is called \'Fluffy'''

А вот и регулярное выражение:

m{ 
    '                   # opening apostrophe
    (?>                 # start non-backtracking group
        [^\\']+         # anything but a backslash or an apostrophe, one or more times
    |                   # or
        (?:                 # group of
            \\ \\? [0-7]{3} # one or two backslashes and three octal digits
        )+                  # one or more times
    |                   # or
        ''              # double apostrophe
    |                   # or
        \\ [\\']        # backslash-escaped apostrophe or backslash
    )*                  # end of group
    '                   # closing apostrophe
}x;
1 голос
/ 13 июня 2010

Если вас не волнует правильность, по крайней мере, на данный момент, не могли бы вы просто попытаться сопоставить обычные строковые литералы в кавычках? Вероятно, что-то вроде

m{
    (?>                     # start of a quote group
        '                   # opening apostrophe
        (?>                 # start non-backtracking group
            [^\\']+         # anything but a backslash or an apostrophe, one or more times
        |                   # or
            \\ .            # backslash-escaped something
        )*                  # end of group
        '                   # closing apostrophe
    )+                      # end of a quote group, many of these
}x;
0 голосов
/ 01 марта 2010

Прежде всего, кажется, что вы пытаетесь сделать две совершенно разные вещи в одном регулярном выражении:

  • Подходит для правильности.
  • Unquoting это.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...