регулярное выражение - ленивый и не захватывая - PullRequest
1 голос
/ 23 декабря 2011

Строка для поиска:

VALUES ('9gfdg', to_date('1876/12/06','YYYY/MM/DD'), null) 

Поиск по регулярному выражению на данный момент:

VALUES\s*\(\s*'?\s*(.+?)\s*'?\s*,\s*'?\s*(.+?)\s*'?\s*,\s*'?\s*(.+?)\s*'?\s*\)

Замените регулярное выражение на 3 группы: т.е. \1 \2 \3

Я стремлюсь крезультат:

9gfdg to_date('1876/12/06' ,'YYYY/MM/DD')  null

, но вместо этого получим (из-за лишней запятой в to_Date, а также ленивый вместо жадного):

9gfdg to_date('1876/12/06 YYYY/MM/DD , null) 

Примечание: это ровно 3 поля (значения в этих 3 полях могут отличаться, но вы понимаете формат, с которым я работаю).т.е. каждое из полей может иметь запятые (обычно символьные значения, могут быть ключевыми словами, такими как ноль, могут быть числами или выражением to_Date.

Движок Regex - VBA / VBscript

У кого-нибудь есть указания по исправлению этого регулярного выражения?

Ответы [ 3 ]

1 голос
/ 23 декабря 2011

В более общем случае вы можете попробовать что-то вроде:

^\s*
VALUES\s*
\(
\s*
(?: '([^']*)' | ( \w+ (?: \( [^()]* \) )? ) )
\s*,\s*
(?: '([^']*)' | ( \w+ (?: \( [^()]* \) )? ) )
\s*,\s*
(?: '([^']*)' | ( \w+ (?: \( [^()]* \) )? ) )
\s*
\)\s*
$

Удалено пробелов:

^\s*VALUES\s*\(\s*(?:'([^']*)'|(\w+(?:\([^()]*\))?))\s*,\s*(?:'([^']*)'|(\w+(?:\([^()]*\))?))\s*,\s*(?:'([^']*)'|(\w+(?:\([^()]*\))?))\s*\)\s*$

Заменить на:

\1\2 \3\4 \5\6

Должно работать для одного вложенного уровня скобок без кавычек в них.

PS: не тестировалось. Вы можете использовать регулярные выражения через интервал, если ваш аромат поддерживает флаг /x.

1 голос
/ 23 декабря 2011

Вот решение.

Обратите внимание на регулярное выражение для $field: это еще одно применение шаблона normal* (special normal*)*, где normal - это не запятая ([^,]) и special запятая, если за ней не следует на две одинарные кавычки (,(?!'')). Однако первый normal делается непустым, используя + вместо *.

Демонстрационный код в perl. Оператор конкатенации строк в perl является точкой:

fge@erwin $ cat t.pl
#!/usr/bin/perl -W
use strict;

# Value separator: a comma optionally surrounded by spaces
my $value_separator = '\s*,\s*';

# Literal "null", and a number
my $null = 'null';
my $number = '\d+';

# Text field
my $normal = '[^,]'; # Anything but a comma
my $special = ",(?!'')"; # A comma, _not_ followed by two single quotes
my $field = "'$normal+(?:$special$normal*)*'"; # a text field

# A to_date() expression
my $to_date  = 'to_date\(\s*' . $field . $value_separator . $field . '\s*\)';

# Any field
my $any_field = '(' . $null . '|' . $number . '|' . $field . '|' . $to_date . ')';

# The full regex
my $full_regex = '^\s*VALUES\s*\(\s*' . $any_field . $value_separator . $any_field
    . $value_separator . $any_field . '\s*\)\s*$';

# This builds a compiled form of the regex
my $re = qr/$full_regex/;

# Read from stdin, try and match (m//), if match, print the three captured groups
while (<STDIN>) {
        m/$re/ and print <<EOF;
Argument 1: -->$1<--
Argument 2: -->$2<--
Argument 3: -->$3<--
EOF
}

Демонстрационный выход:

fge@erwin ~ $ perl t.pl
VALUES ('9gfdg', to_date('1876/12/06','YYYY/MM/DD'), null) 
Argument 1: -->'9gfdg'<--
Argument 2: -->to_date('1876/12/06','YYYY/MM/DD')<--
Argument 3: -->null<--
VALUES('prout', 'ma', 'chere') 
Argument 1: -->'prout'<--
Argument 2: -->'ma'<--
Argument 3: -->'chere'<--
VALUES(324, 'Aiie, a comma', to_date('whatever', 'is there, even commas'))
Argument 1: -->324<--
Argument 2: -->'Aiie, a comma'<--
Argument 3: -->to_date('whatever', 'is there, even commas')<--

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

edit: special в поле - это запятая, за которой не следует две одинарные кавычки, а не одна

1 голос
/ 23 декабря 2011

Если только второй параметр может содержать запятые, вы можете сделать что-то вроде:

^VALUES\s*\(\s*'?([^',]*)'?\s*,\s*(.*?)\s*,\s*'?([^',]*)'?\s*\)$

В противном случае я не знаю, какие функции поддерживает этот регулярный код, так что сложно сделать что-то веселее. Хотя вы всегда можете сделать регулярное выражение для вложенных скобок ограниченной глубины, если (?R) не поддерживается.

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