删除单行注释,但不删除单引号括起来的字符串

时间:2016-04-22 09:43:01

标签: java regex string parsing

我正在创建一个示例代码,它解析我拥有SQL的SQL文件和一个注释的代码块,如:

-- CREATE PROCEDURE
/* 
 Cleaned By : Tej Kiran
 Cleaned On : 05/12/2009 
 -- Procedure [ChambalSchedules] 
*/ 
CREATE procedure [dbo].[ChambalSchedules] 
( 
 @dyid INT = -1, 
 @dy VARCHAR(10) = '', 
 @yr VARCHAR(10) = '', 
 @dt DATETIME = '', 
 @HID INT = 0, 
 @HsID INT = 0, 
 @CID INT = 0, 
 @ScId INT = 0 
) 
AS 
BEGIN 
 DECLARE @BLID BIT 
 DECLARE @BsID BIT 
 DECLARE @BTID BIT 
 DECLARE @BShId BIT 
 SET @BLID = 0 
 SET @BsID = 0 
 SET @BTID = 0 
 SET @BShId = 0 
...
...
...
 SELECT 
 ShID 
 , ShType 
 , ISNULL(list,'---') AS List
 , Dy 
 , ChambalID 
 , CTypeID 
 FROM #testing1
 WHERE 
 Day = @dyid 
 ORDER BY 
 Day 
 ,ShID 
... .
...
END;

我正在使用Java来解析这样的查询。我想清除以--开头并以\n结尾的单行注释,但不想删除引号之间的内容:'text -- text '

我使用了以下正则表达式:

qry= qry.replaceAll("(\s--.*)|((m?)^--.*\n)","");

它在http://regexr.com/中正常工作,但在我的Java代码中它也删除了'---';

qry= qry.replaceAll("(?m)(--.*\\n)", "");

请建议正确的正则表达式。

我有以下情况:

  • 案例1:行以--开头,之后它可能在--\n之间有任何字符或特殊字符(新行字符)

    -- This is my comment line should be removed

  • 案例2:Line启动其他代码,行末有注释。

    Select * from Table; -- GetListFrom table\n

    • 注意:我想删除-- GetListFrom table\n
  • 案例3:如果行在单引号之间包含--,则不执行任何操作。

    SELECT ShID , ShType , ISNULL(list,'---') AS list , Dy , chambalID , CTypeID FROM #testing1 WHERE Dy = @dyid ORDER BY Day ,ShID

    • 在这种情况下,不应删除任何内容。

请建议正确的方法。

1 个答案:

答案 0 :(得分:0)

使用纯正则表达式来解析复杂的问题的一个最大问题是效率。因此,我倾向于支持混合解决方案。

我认为你的大多数行都没有--。可以使用Scanner来获取每一行,并且可以很容易地看到是否存在--

Scanner getLine = new Scanner(qry);
while(getLine.hasNextLine()){
    String line = getLine.nextLine();
    if(line.contains("--")){
        // replacement happens here
    }
}

如此之快,而且非常易读。接下来,我们可以使用正则表达式:

line.replace("^((?:(?:'[^']*')|[^'-])*)--.*", "$1")

现在,当正则表达式匹配时,它会捕获整行。这就是为什么有$1替换所必需的原因。以下部分提供$1

  • '[^']*'匹配引号之间的任何内容

  • [^'-]匹配不是-'

  • 的字符

正则表达式的其余部分捕获--以及行中的其余字符(请记住,正则表达式一次只应用于一行)。

这种方法有些事情没有考虑到。但它比其他方法更强大,因此这些边缘情况不太可能出现:

  • 它仅适用于跨越一行的字符串。
  • 它无法识别字符串中的转义'个字符。
  • 它不喜欢在引号外看到一个短划线。

如果您认为上述任何问题与您的问题相关(或者您遇到其他问题),请随时告诉我,我会看到更新此答案。