SQL과 같은 표현식을 즉시 정규식으로 변환하려면 어떤 코드를 사용해야 합니까?
문제
SQL과 같은 문을 즉석에서 동등한 정규식으로 변환하려고 합니다.
LIKE '%this%'
LIKE 'Sm_th'
LIKE '[C-P]arsen'
이 작업을 수행하는 가장 좋은 방법은 무엇입니까?
추신저는 .Net Framework(C#)에서 이 작업을 수행하려고 합니다.
해결책
다음 Regex는 SQL과 유사한 패턴을 다음의 도움으로 Regex 패턴으로 변환합니다. MatchEvaluator
대리자.대괄호 블록을 올바르게 처리하고 특수 Regex 문자를 이스케이프합니다.
string regexPattern = Regex.Replace(
likePattern,
@"[%_]|\[[^]]*\]|[^%_[]+",
match =>
{
if (match.Value == "%")
{
return ".*";
}
if (match.Value == "_")
{
return ".";
}
if (match.Value.StartsWith("[") && match.Value.EndsWith("]"))
{
return match.Value;
}
return Regex.Escape(match.Value);
});
다른 팁
@Nathan-Baulch의 솔루션 외에도 아래 코드를 사용하여 사용자 정의 이스케이프 문자가 정의된 경우를 처리할 수도 있습니다. LIKE '!%' ESCAPE '!'
통사론.
public Regex ConvertSqlLikeToDotNetRegex(string regex, char? likeEscape = null)
{
var pattern = string.Format(@"
{0}[%_]|
[%_]|
\[[^]]*\]|
[^%_[{0}]+
", likeEscape);
var regexPattern = Regex.Replace(
regex,
pattern,
ConvertWildcardsAndEscapedCharacters,
RegexOptions.IgnorePatternWhitespace);
regexPattern = "^" + regexPattern + "$";
return new Regex(regexPattern,
!m_CaseSensitive ? RegexOptions.IgnoreCase : RegexOptions.None);
}
private string ConvertWildcardsAndEscapedCharacters(Match match)
{
// Wildcards
switch (match.Value)
{
case "%":
return ".*";
case "_":
return ".";
}
// Remove SQL defined escape characters from C# regex
if (StartsWithEscapeCharacter(match.Value, likeEscape))
{
return match.Value.Remove(0, 1);
}
// Pass anything contained in []s straight through
// (These have the same behaviour in SQL LIKE Regex and C# Regex)
if (StartsAndEndsWithSquareBrackets(match.Value))
{
return match.Value;
}
return Regex.Escape(match.Value);
}
private static bool StartsAndEndsWithSquareBrackets(string text)
{
return text.StartsWith("[", StringComparison.Ordinal) &&
text.EndsWith("]", StringComparison.Ordinal);
}
private bool StartsWithEscapeCharacter(string text, char? likeEscape)
{
return (likeEscape != null) &&
text.StartsWith(likeEscape.ToString(), StringComparison.Ordinal);
}
위의 예에서 나는 다음과 같이 공격할 것입니다(나는 C#을 모르기 때문에 일반적인 용어로 말합니다).
그것을 분해하여 좋다 '...', 넣어 ... 조각을 배열로 만듭니다.이스케이프되지 않은 바꾸기 % 표지판 .*, 밑줄은 .로 표시되며, 이 경우에는 [C-P]아르센 정규식으로 직접 변환됩니다.
배열 조각을 파이프로 다시 결합하고 결과를 괄호와 표준 정규식 비트로 묶습니다.
결과는 다음과 같습니다.
/^(.*this.*|Sm.th|[C-P]arsen)$/
여기서 가장 중요한 것은 데이터를 이스케이프할 수 있는 모든 방법과 어떤 와일드카드가 어떤 정규식으로 변환되는지 주의하는 것입니다.
% becomes .*
_ becomes .
Perl 모듈을 찾았습니다. 정규식::와일드카드.이식을 시도하거나 Perl.NET을 사용해 볼 수 있습니다.당신도 스스로 뭔가를 쓸 수 있을 것 같은 느낌이 듭니다.
제휴하지 않습니다 StackOverflow