要搜索的字符串:
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个字段中的值可能不同,但您可以了解我正在努力解决的格式)。即每个字段都可以有逗号(通常是字符值,可以是关键字,如null,可以是数字,也可以是to_Date表达式。
正则表达式引擎是VBA / VBscript
任何人都有关于修复此正则表达式的任何指示?
答案 0 :(得分:1)
如果只有第二个参数可以包含逗号,您可以执行以下操作:
^VALUES\s*\(\s*'?([^',]*)'?\s*,\s*(.*?)\s*,\s*'?([^',]*)'?\s*\)$
否则我不知道正则表达式支持哪些功能,所以很难让一些更有趣的东西。如果不支持(?R)
,你总是可以制作有限深度的嵌套括号正则表达式。
答案 1 :(得分:1)
对于更一般的情况,您可以尝试以下方式:
^\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
标志,你通常可以使用间隔正则表达式。
答案 2 :(得分:1)
这是一个解决方案。
请注意$field
的正则表达式:它是normal* (special normal*)*
模式的另一个应用程序,normal
只是逗号([^,]
)和{{1}一个逗号,只要它后面没有两个单引号(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')<--
实际上是一个逗号后面没有两个单引号,而不是一个