正则表达式从SQL语句中删除注释

时间:2012-03-13 19:09:07

标签: sql regex vbscript

我正在尝试使用正则表达式从SQL语句中删除注释。

这个正则表达式几乎可以工作:

(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|'(?:[^']|'')*'|(--.*)

除了最后一部分没有处理“ - ”评论非常好。问题是处理SQL字符串,用''。

分隔

例如,如果我有

SELECT ' -- Hello -- ' FROM DUAL

它不应该匹配,但它匹配。

这是在ASP / VBscript中。

我考虑过从右到左匹配,但我不认为VBScript的正则表达式引擎支持它。也试图摆弄负面的背后,但结果并不好。

8 个答案:

答案 0 :(得分:5)

在PHP中,我使用此代码取消注释SQL:

$sqlComments = '@(([\'"]).*?[^\\\]\2)|((?:\#|--).*?$|/\*(?:[^/*]|/(?!\*)|\*(?!/)|(?R))*\*\/)\s*|(?<=;)\s+@ms';
/* Commented version
$sqlComments = '@
    (([\'"]).*?[^\\\]\2) # $1 : Skip single & double quoted expressions
    |(                   # $3 : Match comments
        (?:\#|--).*?$    # - Single line comments
        |                # - Multi line (nested) comments
         /\*             #   . comment open marker
            (?: [^/*]    #   . non comment-marker characters
                |/(?!\*) #   . ! not a comment open
                |\*(?!/) #   . ! not a comment close
                |(?R)    #   . recursive case
            )*           #   . repeat eventually
        \*\/             #   . comment close marker
    )\s*                 # Trim after comments
    |(?<=;)\s+           # Trim after semi-colon
    @msx';
*/
$uncommentedSQL = trim( preg_replace( $sqlComments, '$1', $sql ) );
preg_match_all( $sqlComments, $sql, $comments );
$extractedComments = array_filter( $comments[ 3 ] );
var_dump( $uncommentedSQL, $extractedComments );

答案 1 :(得分:1)

正如你所说,你的正则表达式的其余部分都很好,我专注于最后一部分。您需要做的就是验证--是否在开头,然后确保在超过2时删除所有破折号。结束正则表达式在

之下
(^[--]+)

以上就是你要删除注释破折号而不是整行。如果您确实希望其后的所有内容都在行的末尾,也可以运行以下内容,

(^--.*)

答案 2 :(得分:1)

此代码适用于我:

function strip_sqlcomment ($string = '') {
    $RXSQLComments = '@(--[^\r\n]*)|(\#[^\r\n]*)|(/\*[\w\W]*?(?=\*/)\*/)@ms';
    return (($string == '') ?  '' : preg_replace( $RXSQLComments, '', $string ));
}

通过一些正则表达式调整,它可以用来删除任何语言的评论

答案 3 :(得分:0)

最初,我使用了@Adrien Gibrat的解决方案。但是,我遇到了一种情况,它没有正确地解析引用的字符串,如果我在其中有任何前面的' - '。我最后写了这个,而不是:

'[^']*(?!\\)'(*SKIP)(*F)       # Make sure we're not matching inside of quotes
|(?m-s:\s*(?:\-{2}|\#)[^\n]*$) # Single line comment
|(?:
  \/\*.*?\*\/                  # Multi-line comment
  (?(?=(?m-s:\h+$))         # Get trailing whitespace if any exists and only if it's the rest of the line
    \h+
  )
)

# Modifiers used: 'xs' ('g' can be used as well, but is enabled by default in PHP)

请注意,当PCRE可用时应使用此功能。所以,就我而言,我在我的PHP库中使用了这种变体。

Example

答案 4 :(得分:0)

请参阅我的回答here。它适用于行注释块注释,甚至嵌套块注释。我想你需要在平衡组中使用正则表达式,而VFAcript中没有AFAIK。

答案 5 :(得分:0)

删除/ ** /和-注释

function unComment($sql){

        $re = '/(--[^\n]*)/i';
        $sql = preg_replace( $re, '', $sql );

        $sqlComments = '@(([\'"]).*?[^\\\]\2)|((?:\#|--).*?$|/\*(?:[^/*]|/(?!\*)|\*(?!/)|(?R))*\*\/)\s*|(?<=;)\s+@ms';
        $uncommentedSQL = trim( preg_replace( $sqlComments, '$1', $sql ) );
        preg_match_all( $sqlComments, $sql, $comments );
        $sql = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', trim($uncommentedSQL));


        return $sql;
    }

答案 6 :(得分:0)

对于Node.js,请参见pg-minify库。它可与PostgreSQL,MS-SQL和MySQL脚本一起使用。

它可以处理所有类型的注释,并将生成的SQL压缩到最低限度,以优化需要发送到服务器的内容。

答案 7 :(得分:-1)

对于所有PHP人员:请使用此库 - https://github.com/jdorn/sql-formatter。我几年来一直在处理从SQL中剥离注释的问题,唯一有效的解决方案是令牌器/状态机,我懒得写入。几天前我发现了这个lib并通过它运行了120k查询,发现只有一个bug(https://github.com/jdorn/sql-formatter/issues/93),它立即在我们的分叉https://github.com/keboola/sql-formatter中修复。

用法很简单

$query <<<EOF
/* 
  my comments 
*/
SELECT 1;
EOF;

$bareQuery = \SqlFormatter::removeComments($query);
// prints "SELECT 1;"
print $bareQuery;