复杂的正则表达式仅识别带括号的参数

Posted

技术标签:

【中文标题】复杂的正则表达式仅识别带括号的参数【英文标题】:complex regex to identify parameters with brackets only 【发布时间】:2015-02-20 10:07:18 【问题描述】:

我正在尝试构建一个正则表达式,它将识别括号内的参数并忽略 pl/sql cmets(单行 -- 和多行 /* */)

例如:

create or replace table_name   ---sfjdslkfjslkfjslkfjdsfsdf

**(var1 in out number, var2 number)**

/* sdfls 
sfdsd jfs
 sfs f
sd f
sfsf */

AS 

BEGIN

(var1 in out number, var2 number) 应该只匹配。它还应考虑以下情况:

没有 cmets(单行或多行) 参数前后只有单行 cmets 参数前后只有多行cmets 没有参数

假设:

参数始终用括号 () 括起来 过程有时可以没有参数,但在 AS BEGIN 子句之前有 cmets(单行或多行 cmets) 程序以create or replace table_name 开头 我们只想阅读直到AS BEGIN 子句

换句话说,我需要找到在任何 cmets(单行或多行)之外且位于 AS BEGIN 子句之前的第一个左括号 '(' 的索引。

更新:

我已经设法使用以下正则表达式匹配 cmets:

(?:\/\*(?:[\s\S]*?)\*\/)|(?:\-\-(?:.*)$)

例如这里它将匹配所有的 cmets:

create or replace table_name 

-- sdlfksl kjs slkjslds js

/* lsdjfdkj 
s fskjfs
 sf sf
 sdf;;''
sfs fs
 */

 (hello number, var2 number)

 --sdflksf

 /*sl --sdflks s kdjfls())(fsfs */


AS

BEGIN

我现在可以在 Java 中执行此操作,以识别任何匹配组之外的第一个左括号。但是,如果我可以忽略匹配组并仅匹配括号中的一个参数,那会更容易。

编辑

这不是要求使用 pl/sql 或 sqlplus 或其他什么的解决方案。我有一些 pl/sql 过程存储在需要修改和添加新参数的文件中。我正在使用 Java 来做到这一点,并在 Java 中使用循环和正则表达式的组合。

【问题讨论】:

查询USER_ARGUMENTS 查看。看我的回答。 为什么要在 PL/SQL 中这样做?在 PL/SQL 中实现解析器是 PITA。我也怀疑它可以使用正则表达式来完成,调用约定不是那么简单。恐怕你需要一个真正的解析器。 检查这个项目:github.com/porcelli/plsql-parser。并使用“仅”生成的词法分析器。然后迭代从此词法分析器返回的标记。 有关可能的过程参数声明,请参阅 Oracle SQL 参考:docs.oracle.com/database/121/LNPLS/… 在问题中看到您的编辑。通过你的方法添加新参数后,PL/SQL程序编译成功的保证是什么? 【参考方案1】:

不知道为什么要重新发明***。在 Oracle 中,您可以使用 *_ARGUMENTS 视图来获取所有参数的列表。

例如,

SQL> CREATE OR REPLACE
  2  PROCEDURE p(
  3      in_date  DATE,
  4      out_text VARCHAR2)
  5  AS
  6  BEGIN
  7    NULL;
  8  END;
  9  /

Procedure created.

SQL>
SQL> SELECT object_name,
  2    package_name,
  3    argument_name,
  4    position,
  5    data_type
  6  FROM USER_ARGUMENTS
  7  WHERE OBJECT_NAME = 'P';

OBJECT_NAM PACKAGE_NA ARGUMENT_NAME     POSITION DATA_TYPE
---------- ---------- --------------- ---------- ---------
P                     OUT_TEXT                 2 VARCHAR2
P                     IN_DATE                  1 DATE

SQL>

【讨论】:

这是关于编辑一些 pl/sql 脚本的。我正在放置一些新参数,我需要先用括号识别参数,获取任何 cmets 之外的第一个左括号的索引,然后在其中插入新参数。 这是我的全部问题。为什么要手动完成所有这些操作?无论如何,您都会使用我建议的方法获得参数。 我对现有的论点不感兴趣。我需要将新的添加到本地存储的 pl/sql 文件中。我正在用 Java 打开每个文件,并尝试以编程方式向每个过程添加新参数。为此,您需要考虑我在原始问题中提到的事情。有数千个文件,因此需要以编程方式进行。 好的。我试图帮助您满足您的初始要求:-,我正在尝试构建一个正则表达式,它将识别括号内的参数并忽略 pl/sql cmets 我希望它对您有用。不确定您是否投了反对票或其他人,但我敢打赌这是了解您的 PL/SQL 程序参数的最佳方法。我希望我可以进一步帮助您解决您的需要,但是,很抱歉我不明白这个要求。如果您认为它值得帮助,请将其标记为已回答。祝你好运!【参考方案2】:

我不熟悉 Oracle 的正则表达式风格,但我创建了一个适用于大多数正则表达式引擎的模式。我知道 mysql 有一个完全不同的语法,所以这很可能在 Oracle 中也是如此,但总体思路是这样的:

create or replace table_name(?:(?!AS\s+BEGIN)(?:--[^\n]*(?:\n|$)|\/\*(?:[^*]|\*(?!\/))*\*\/|(?!\/\*|--)[^(]))*\(([^)]+)

Debuggex Demo

这是一个“匹配this,除了上下文ABC 方法也使用here 并深入解释in this SO answer .结合我们匹配的任何内容后面都没有AS\s+BEGIN的要求。

您可以在Debuggex Demo 中看到括号之间的正确部分在捕获组1 中匹配。同样,第二个create 没有参数,实际上没有任何匹配项(即使在 cmets 和 AS BEGIN 之后有括号。

手头的任务是将其移植到 Oracle 的正则表达式风格。

【讨论】:

以上是关于复杂的正则表达式仅识别带括号的参数的主要内容,如果未能解决你的问题,请参考以下文章

带括号的数学运算的正则表达式

带括号的正则表达式测试[重复]

正则表达式:用“|”匹配带括号的字符串运算符 [重复]

“现代”正则表达式的识别能力

Python 正则表达式 利用括号分组

正则表达式匹配括号或括号内的字符串中的数字