我需要查找并删除MySQL查询中的所有注释。我遇到的问题是避免使用引号或反引号中的注释标记( - ,#,/ * ... * /)。
答案 0 :(得分:6)
在PHP中,我使用此代码取消注释SQL:
$sqlComments = '@(([\'"`]).*?[^\\\]\2)|((?:\#|--).*?$|/\*(?:[^/*]|/(?!\*)|\*(?!/)|(?R))*\*\/)\s*|(?<=;)\s+@ms';
/* Commented version
$sqlComments = '@
(([\'"`]).*?[^\\\]\2) # $1 : Skip single & double quoted + backticked 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 :(得分:3)
不幸的是,你要做的事情需要一个无上下文语法,不能用正则表达式完成。这是因为嵌套,而在计算机科学理论中,我们需要一个堆栈来跟踪何时嵌套在引号或什么不是。 (从技术上讲,这需要一个推倒自动机而不是常规语言.Blah blah学术界等等......)实现并不难,但必须在程序上完成,老实说,它可能需要比你想要的更多努力花费。
如果您不介意剪切和粘贴,可以使用SQLInform。在线模式是免费的,支持删除评论。
<强>更新强>
考虑到我在下面收到的评论,我玩了MySQL编辑器。我错了 - 他们实际上禁止筑巢任何比一层更深的东西。您不能再在评论中嵌套评论(如果可能的话)。无论如何,我只会为SQLInform链接留下我的答案。
答案 2 :(得分:0)
有人为你写过。转换为您需要的任何语言。
Use Regular Expressions to Clean SQL Statements
以下是答案中包含的C#翻译,以防原始链接消失。我没有测试过这个,但它看起来很合理。
public static string ToRaw(string commandText)
{
RegexOptions regExOptions = (RegexOptions.IgnoreCase | RegexOptions.Multiline);
string rawText=commandText;
string regExText = @”(‘(”|[^'])*’)|([\r|\n][\s| ]*[\r|\n])|(–[^\r\n]*)|(/\*[\w\W]*?(?=\*/)\*/)”;
//string regExText = @”(‘(”|[^'])*’)|[\t\r\n]|(–[^\r\n]*)|(/\*[\w\W]*?(?=\*/)\*/)”;
//’Replace Tab, Carriage Return, Line Feed, Single-row Comments and
//’Multi-row Comments with a space when not included inside a text block.
MatchCollection patternMatchList = Regex.Matches(rawText, regExText, regExOptions);
int iSkipLength = 0;
for (int patternIndex = 0; patternIndex < patternMatchList.Count; patternIndex++)
{
if (!patternMatchList[patternIndex].Value.StartsWith("'") && !patternMatchList[patternIndex].Value.EndsWith("'"))
{
rawText = rawText.Substring(0, patternMatchList[patternIndex].Index – iSkipLength) + " " + rawText.Substring(patternMatchList[patternIndex].Index – iSkipLength + patternMatchList[patternIndex].Length);
iSkipLength += (patternMatchList[patternIndex].Length – " ".Length);
}
}
//'Remove extra spacing that is not contained inside text qualifers.
patternMatchList = Regex.Matches(rawText, "'([^']|'')*'|[ ]{2,}", regExOptions);
iSkipLength = 0;
for (int patternIndex = 0; patternIndex < patternMatchList.Count; patternIndex++)
{
if (!patternMatchList[patternIndex].Value.StartsWith("'") && !patternMatchList[patternIndex].Value.EndsWith("'"))
{
rawText = rawText.Substring(0, patternMatchList[patternIndex].Index – iSkipLength)+" " + rawText.Substring(patternMatchList[patternIndex].Index – iSkipLength + patternMatchList[patternIndex].Length);
iSkipLength += (patternMatchList[patternIndex].Length – " ".Length);
}
}
//'Return value without leading and trailing spaces.
return rawText.Trim();
}
答案 3 :(得分:0)
此代码适用于我:
function strip_sqlcomment ($string = '') {
$RXSQLComments = '@('(''|[^'])*')|(--[^\r\n]*)|(\#[^\r\n]*)|(/\*[\w\W]*?(?=\*/)\*/)@ms';
return (($string == '') ? '' : preg_replace( $RXSQLComments, '', $string ));
}
通过一些正则表达式调整,它可以用来删除任何语言的评论
答案 4 :(得分:-1)
不幸的是,您只能使用正则表达式进行非常有限的SQL格式化。主要原因是有例如你不想删除的注释或你不能低/大写的标记,因为它们是文字的一部分,并且找到文字的开头和结尾并不总是很容易,因为不同的SQL方言使用不同的封闭字符,有时甚至使用几个字符包含文字。有时人们会将SQL片段放在评论中以供以后重复使用。您不希望重新格式化这些SQL。 当您使用正则表达式更改SQL语句时,请在数据库工具中再次运行更改的SQL,以确保您没有更改任何逻辑。我听说人们在没有检查结果的情况下在100个od SQL文件上运行正则表达式。我认为这是一个非常危险的步骤。永远不要改变正在运行的SQL ;-)