[SQL] 모두 일치하는 정규 표현식은 T-SQL 스크립트에 댓글
SQL모두 일치하는 정규 표현식은 T-SQL 스크립트에 댓글
나는 T-SQL의 블록의 모든 주석을 캡처하는 정규 표현식이 필요합니다. 표현은 닷넷 정규식 클래스와 함께 작동하도록해야합니다.
이제 나는 다음과 T-SQL 있다고 가정 해 봅시다 :
-- This is Comment 1
SELECT Foo FROM Bar
GO
-- This is
-- Comment 2
UPDATE Bar SET Foo == 'Foo'
GO
/* This is Comment 3 */
DELETE FROM Bar WHERE Foo = 'Foo'
/* This is a
multi-line comment */
DROP TABLE Bar
나는 그들을 제거 할 수 있습니다 그래서, 멀티 라인 포함한 코멘트, 모두를 캡처해야합니다.
편집 : 그것은 모든하지만 주석을 취하는 식을 가지고 같은 목적을 제공합니다.
해결법
-
==============================
1.이 작업을해야합니다 :
이 작업을해야합니다 :
(--.*)|(((/\*)+?[\w\W]+?(\*/)+))
-
==============================
2.PHP에서, 나는 주석 SQL에 (이되는 주석 버전 -> X 수정을)이 코드를 사용하고 있습니다 :
PHP에서, 나는 주석 SQL에 (이되는 주석 버전 -> X 수정을)이 코드를 사용하고 있습니다 :
trim( preg_replace( '@ (([\'"]).*?[^\\\]\2) # $1 : Skip single & double quoted expressions |( # $3 : Match comments (?:\#|--).*?$ # - Single line comment | # - 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', '$1', $sql ) );
짧은 버전 :
trim( preg_replace( '@(([\'"]).*?[^\\\]\2)|((?:\#|--).*?$|/\*(?:[^/*]|/(?!\*)|\*(?!/)|(?R))*\*\/)\s*|(?<=;)\s+@ms', '$1', $sql ) );
-
==============================
3.이 코드를 사용 :
이 코드를 사용 :
StringCollection resultList = new StringCollection(); try { Regex regexObj = new Regex(@"/\*(?>(?:(?!\*/|/\*).)*)(?>(?:/\*(?>(?:(?!\*/|/\*).)*)\*/(?>(?:(?!\*/|/\*).)*))*).*?\*/|--.*?\r?[\n]", RegexOptions.Singleline); Match matchResult = regexObj.Match(subjectString); while (matchResult.Success) { resultList.Add(matchResult.Value); matchResult = matchResult.NextMatch(); } } catch (ArgumentException ex) { // Syntax error in the regular expression }
다음과 같은 입력으로 :
-- This is Comment 1 SELECT Foo FROM Bar GO -- This is -- Comment 2 UPDATE Bar SET Foo == 'Foo' GO /* This is Comment 3 */ DELETE FROM Bar WHERE Foo = 'Foo' /* This is a multi-line comment */ DROP TABLE Bar /* comment /* nesting */ of /* two */ levels supported */ foo...
이러한 일치를 생성합니다 :
-- This is Comment 1 -- This is -- Comment 2 /* This is Comment 3 */ /* This is a multi-line comment */ /* comment /* nesting */ of /* two */ levels supported */
내 인생에서 내가 한 레벨이 사용보다 더 본 적이 있지만 이것은 단지, 중첩 된 주석의 2 개 수준을 일치하지 않는 것이. 이제까지.
-
==============================
4.나는 일반 정규 expressons를 사용하여 모든 SQL 주석을 제거이 기능을했다. 및 블록 주석 (중첩 된 블록 주석이있는 경우에도) (A LINEBREAK 후이없는 경우에도)은 두 줄 주석을 제거합니다. (당신은 SQL 프로 시저 안에 뭔가를 검색 할 경우 유용하지만 당신은 문자열을 무시하려는)이 기능은 리터럴을 대체 할 수 있습니다.
나는 일반 정규 expressons를 사용하여 모든 SQL 주석을 제거이 기능을했다. 및 블록 주석 (중첩 된 블록 주석이있는 경우에도) (A LINEBREAK 후이없는 경우에도)은 두 줄 주석을 제거합니다. (당신은 SQL 프로 시저 안에 뭔가를 검색 할 경우 유용하지만 당신은 문자열을 무시하려는)이 기능은 리터럴을 대체 할 수 있습니다.
하지만, 더 중요한 것은 내가 블록 주석이 있기 때문에 (균형 그룹을 사용) 정규식 재 작성했다 - ""내 코드는 내가 "//"(으)로 변경 줄 주석에 있었다, 그래서 (C #을 코멘트에 관한 것입니다)이 답변에 기반 C #은하지 않지만 SQL은, 중첩 된 블록 주석을 수 있습니다.
또한, 나는 대신 주석을 제거의 그냥 공백으로 의견을 채우고이 "preservePositions"인수를 가지고있다. 각 SQL 명령의 원래 위치를 유지하려면 그 경우에 당신은 원래 의견을 유지하면서 원래의 스크립트를 조작 할 필요가 유용합니다.
Regex everythingExceptNewLines = new Regex("[^\r\n]"); public string RemoveComments(string input, bool preservePositions, bool removeLiterals=false) { //based on https://stackoverflow.com/questions/3524317/regex-to-strip-line-comments-from-c-sharp/3524689#3524689 var lineComments = @"--(.*?)\r?\n"; var lineCommentsOnLastLine = @"--(.*?)$"; // because it's possible that there's no \r\n after the last line comment // literals ('literals'), bracketedIdentifiers ([object]) and quotedIdentifiers ("object"), they follow the same structure: // there's the start character, any consecutive pairs of closing characters are considered part of the literal/identifier, and then comes the closing character var literals = @"('(('')|[^'])*')"; // 'John', 'O''malley''s', etc var bracketedIdentifiers = @"\[((\]\])|[^\]])* \]"; // [object], [ % object]] ], etc var quotedIdentifiers = @"(\""((\""\"")|[^""])*\"")"; // "object", "object[]", etc - when QUOTED_IDENTIFIER is set to ON, they are identifiers, else they are literals //var blockComments = @"/\*(.*?)\*/"; //the original code was for C#, but Microsoft SQL allows a nested block comments // //https://msdn.microsoft.com/en-us/library/ms178623.aspx //so we should use balancing groups // http://weblogs.asp.net/whaggard/377025 var nestedBlockComments = @"/\* (?> /\* (?<LEVEL>) # On opening push level | \*/ (?<-LEVEL>) # On closing pop level | (?! /\* | \*/ ) . # Match any char unless the opening and closing strings )+ # /* or */ in the lookahead string (?(LEVEL)(?!)) # If level exists then fail \*/"; string noComments = Regex.Replace(input, nestedBlockComments + "|" + lineComments + "|" + lineCommentsOnLastLine + "|" + literals + "|" + bracketedIdentifiers + "|" + quotedIdentifiers, me => { if (me.Value.StartsWith("/*") && preservePositions) return everythingExceptNewLines.Replace(me.Value, " "); // preserve positions and keep line-breaks // return new string(' ', me.Value.Length); else if (me.Value.StartsWith("/*") && !preservePositions) return ""; else if (me.Value.StartsWith("--") && preservePositions) return everythingExceptNewLines.Replace(me.Value, " "); // preserve positions and keep line-breaks else if (me.Value.StartsWith("--") && !preservePositions) return everythingExceptNewLines.Replace(me.Value, ""); // preserve only line-breaks // Environment.NewLine; else if (me.Value.StartsWith("[") || me.Value.StartsWith("\"")) return me.Value; // do not remove object identifiers ever else if (!removeLiterals) // Keep the literal strings return me.Value; else if (removeLiterals && preservePositions) // remove literals, but preserving positions and line-breaks { var literalWithLineBreaks = everythingExceptNewLines.Replace(me.Value, " "); return "'" + literalWithLineBreaks.Substring(1, literalWithLineBreaks.Length - 2) + "'"; } else if (removeLiterals && !preservePositions) // wrap completely all literals return "''"; else throw new NotImplementedException(); }, RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace); return noComments; }
테스트 1 (첫번째 원본, 다음 제거 의견, 지난 제거 의견 / 리터)
[select /* block comment */ top 1 'a' /* block comment /* nested block comment */*/ from sys.tables --LineComment union select top 1 '/* literal with */-- lots of comments symbols' from sys.tables --FinalLineComment] [select top 1 'a' from sys.tables union select top 1 '/* literal with */-- lots of comments symbols' from sys.tables ] [select top 1 ' ' from sys.tables union select top 1 ' ' from sys.tables ]
테스트 2 (첫번째 원래 다음 제거 의견, 지난 제거 의견 / 리터)
Original: [create table [/*] /* -- huh? */ ( "-- --" integer identity, -- /* [*/] varchar(20) /* -- */ default '*/ /* -- */' /* /* /* */ */ */ ); go] [create table [/*] ( "-- --" integer identity, [*/] varchar(20) default '*/ /* -- */' ); go] [create table [/*] ( "-- --" integer identity, [*/] varchar(20) default ' ' ); go]
-
==============================
5.이것은 나를 위해 작동합니다 :
이것은 나를 위해 작동합니다 :
(/\*(.|[\r\n])*?\*/)|(--(.*|[\r\n]))
또는 * / .. * / 블록 내에 포함 - 그것은 모든 코멘트로 시작 일치
-
==============================
6.나는 (Oracle 또는 MySQL의 반대)는 Microsoft SQL Server를 사용하고 참조하십시오. 당신이 정규식의 요구 사항을 완화하는 경우, 그것은 마이크로 소프트의 파서를 사용 (2012 년 이후) 지금 가능합니다 :
나는 (Oracle 또는 MySQL의 반대)는 Microsoft SQL Server를 사용하고 참조하십시오. 당신이 정규식의 요구 사항을 완화하는 경우, 그것은 마이크로 소프트의 파서를 사용 (2012 년 이후) 지금 가능합니다 :
using Microsoft.SqlServer.Management.TransactSql.ScriptDom; ... public string StripCommentsFromSQL( string SQL ) { TSql110Parser parser = new TSql110Parser( true ); IList<ParseError> errors; var fragments = parser.Parse( new System.IO.StringReader( SQL ), out errors ); // clear comments string result = string.Join ( string.Empty, fragments.ScriptTokenStream .Where( x => x.TokenType != TSqlTokenType.MultilineComment ) .Where( x => x.TokenType != TSqlTokenType.SingleLineComment ) .Select( x => x.Text ) ); return result; }
SQL에서 댓글을 분리를 참조하십시오
-
==============================
7.PG-작게하다,과 PostgreSQL을위한뿐만 아니라, MS-SQL에 대한뿐만 아니라 - 다음은 잘 작동합니다.
PG-작게하다,과 PostgreSQL을위한뿐만 아니라, MS-SQL에 대한뿐만 아니라 - 다음은 잘 작동합니다.
우리는 주석을 제거하면 아마도, 그 수단 스크립트는 더 이상 읽기, 동시에 그것을 축소에 대한없는 좋은 아이디어이다.
그 라이브러리는 스크립트 축약의 일환으로 모든 댓글을 삭제합니다.
from https://stackoverflow.com/questions/7690380/regular-expression-to-match-all-comments-in-a-t-sql-script by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 는 SQL 쿼리에 사용되는 테이블 목록 (0) | 2020.06.09 |
---|---|
[SQL] DB2의 쿼리에서 구분 된 문자열을 만들기 (0) | 2020.06.09 |
[SQL] MYSQL - IN과 존재의 차이 (0) | 2020.06.09 |
[SQL] DATE에 시간대와 오라클 변환 TIMESTAMP (0) | 2020.06.09 |
[SQL] 다른 컬럼에서 순서에 따라 그룹에서 하나 개의 값을 선택 (0) | 2020.06.09 |