5

我正在为一些 Oracle 命令编写解析器,例如

LOAD DATA
  INFILE  /DD/DATEN
TRUNCATE
PRESERVE BLANKS
INTO TABLE aaa.bbb
( some parameters... )

我已经创建了一个正则表达式来匹配整个命令。我现在正在寻找一种方法来捕获输入文件的名称(例如这里的“/DD/DATEN”)。我的问题是使用以下正则表达式只会返回第一组的最后一个字符(“N”)。

^\s*LOAD DATA\s*INFILE\s*(\w|\\|/)+\s*$

正则表达式可视化

调试演示

有任何想法吗?提前谢谢了

编辑:在@HamZa 的问题之后,这里将是解析Oracle LOAD DATA INFILE 命令的整个正则表达式 (虽然简化了):

^\s*LOAD DATA\s*INFILE\s*((?:\w|\\|/)+)\s*((?:TRUNCATE|PRESERVE BLANKS)\s*){0,2}\s*INTO TABLE\s*((?:\w|\.)+)\s*\(\s*((\w+)\s*POSITION\s*\(\s*\d+\s*\:\s*\d+\s*\)\s*((DATE\s*\(\s*(\d+)\s*\)\s*\"YYYY-MM-DD\")|(INTEGER EXTERNAL)|(CHAR\s*\(\s*(\d+)\s*\)))\s*\,{0,1}\s*)+\)\s*$

正则表达式可视化

调试演示

4

2 回答 2

3

让我们指出您的正则表达式中的错误行为者(\w|\\|/)+。这里会发生什么?
您正在匹配一个单词字符或一个反斜杠并将其放入第 1 组(\w|\\|/),然后您告诉正则表达式引擎执行此操作一次或多次+。您真正想要的是在对它们进行分组之前多次匹配这些字符。因此,您可能会使用不匹配的组(?:): ((?:\w|\\|/)+)

您可能会注意到您毕竟可以只使用一个字符类([\w\\/]+)。因此,您的正则表达式可能看起来像

^\s*LOAD DATA\s*INFILE\s*([\w\\/]+)\s*$

附带说明:$如果您不使用多行模式,该结束锚将导致您的正则表达式失败。还是您故意没有发布完整的正则表达式:)?

于 2013-11-10T19:43:03.377 回答
2

没有测试但是...

^\s*LOAD DATA\s*INFILE\s*(\S+)\s*$
于 2013-11-10T19:37:57.010 回答