复杂的正则表达式仅识别带括号的参数
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,除了上下文A
、B
或C
” 方法也使用here 并深入解释in this SO answer .结合我们匹配的任何内容后面都没有AS\s+BEGIN
的要求。
您可以在Debuggex Demo 中看到括号之间的正确部分在捕获组1 中匹配。同样,第二个create
没有参数,实际上没有任何匹配项(即使在 cmets 和 AS BEGIN
之后有括号。
手头的任务是将其移植到 Oracle 的正则表达式风格。
【讨论】:
以上是关于复杂的正则表达式仅识别带括号的参数的主要内容,如果未能解决你的问题,请参考以下文章