如何告诉正则表达式检查整个子字符串?
Posted
技术标签:
【中文标题】如何告诉正则表达式检查整个子字符串?【英文标题】:How to Tell Regex to Check Whole Sub-String? 【发布时间】:2013-12-04 03:17:24 【问题描述】:首先是我正在使用的正则表达式:
String pattern = @"Create(\s+)Table(\s+)(\([a-z0-9]+\))(\s+)Columns(\s+)((\(([a-z0-9]+);(INTEGER|DECIMAL|STRING);(\d1,3);(((YES|NO);)3)([a-z0-9]+)\))+)";
Match CMD = Regex.Match(Command, pattern, RegexOptions.IgnoreCase);
if (CMD.Success)
return true;
此正则表达式对以下模式按预期工作:
1) 创建表 (MARKS) 列(fountains;StriNg;999;NO;YES;NO;wicked)(rivers;String;500;NO;YES;NO;sweet)
2) 创建表 (MARKS) 列 (ID;Integer;4;YES;YES;YES;0) (riversString;50;NO;YES;NO;sweet)
在第一个模式中,整个字符串是匹配的,但在第二个模式中,只有子字符串 创建表 (MARKS) 列 (ID;Integer;42;YES;YES;YES;0) 匹配
现在它为以下模式返回 false false:
3)创建表 (MARKS) 列 (IDInteger;42;YES;YES;YES;0) (rivers;String;500;NO;YES;NO;sweet)
第二个模式和第三个模式有相同的错误,但唯一的区别是在第二个模式中匹配 \(([a-z0-9]+);(INTEGER|DECIMAL|STRING) ;(\d1,3);(((YES|NO);)3)([a-z0-9]+)\) 在字符串结尾之前已经出现并且因此正则表达式返回 true。
现在我的问题是如何告诉拒绝继续匹配直到字符串结尾?
所以基本上是这样的:不是或除了加号(这意味着一个或多个匹配prevoius)我想要=>一个或多个匹配直到行尾。这样,第三个将导致子字符串 Create Table (MARKS) Columns (rivers;String;500;NO;YES;NO;sweet) 来自 Create Table (MARKS) Columns (IDInteger ;42;YES;YES;YES;0) (rivers;String;500;NO;YES;NO;sweet)
【问题讨论】:
【参考方案1】:使用开始 (^) 和结束 ($) 符号,例如:
String patter = @"^\d+$";
【讨论】:
是的,我知道这些符号,但只是将它们放在开头或结尾仍然会为第三个模式返回 false? 那么这是主模式的问题,而不是线条边框 是的,主要模式存在问题,这就是为什么要寻求帮助?我尽力解释了这一点【参考方案2】:将\s*?
放在Columns(...)
组的右括号之后,以匹配两个Columns
组之间的0+(惰性)空格:
Create(\s+)Table(\s+)(\([a-z0-9]+\))(\s+)Columns(\s+)((\(([a-z0-9]+);(INTEGER|DECIMAL|STRING);(\d1,3);(((YES|NO);)3)([a-z0-9]+)\)\s*?)+)
最后一个字符串不匹配,因为您忘记了 ID 和整数之间的 ;
。
编辑:
好的,我明白你需要什么了。
这匹配 Columns
组之间的 0+ 个空格并继续搜索直到找到有效组。
Create(\s+)Table(\s+)(\([a-z0-9]+\))(\s+)Columns(\s*\([^)]*\))*(\s*\(([a-z0-9]+);(INTEGER|DECIMAL|STRING);(\d1,3);(((YES|NO);)3)([a-z0-9]+)\))+
查看 RegEx101 http://regex101.com/r/rU6eJ4
编辑 2:
这个只匹配同一行的字符串:
Create[^\S\n]+Table[^\S\n]+(\([a-z0-9]+\))[^\S\n]+Columns([^\S\n]*\([^)]*\))*([^\S\n]*\(([a-z0-9]+);(INTEGER|DECIMAL|STRING);(\d1,3);(((YES|NO);)3)([a-z0-9]+)\))+
【讨论】:
是的,我是故意这样做的....但是子字符串“创建表(标记)列(河流;字符串;500;否;是;否;甜)”与模式匹配,但因为“ (IDInteger;42;YES;YES;YES;0)" 在 "(rivers;String;500;NO;YES;NO;sweet)" 前面,它返回 false,但我希望这种模式(模式 3)为真 所以你需要在第一个;
上指定?
修饰符
我明白你的意思,我重构了我的代码并完全改变了我的正则表达式......请参阅我的答案。谢谢
@FabioDelarias 我还添加了一个只匹配同一行上的字符串的编辑(\s
也匹配换行符)。【参考方案3】:
不要只使用开始 (^) 和结束 ($) 符号,使用全局修饰符可能会解决这个特定问题。
字符串模式 = @"/^\d+$/g";
【讨论】:
【参考方案4】:好的,所以基本上我决定将我的正则表达式分解为两个正则表达式:
String pattern = @"Create(\s+)Table(\s+)(\([a-z0-9]+\))(\s+)Columns(\s+)(((\([a-z0-9;]+\))\s*)+)";
Match CMD = Regex.Match(Command, pattern, RegexOptions.IgnoreCase);
if (CMD.Success)
String SubCommand = CMD.Groups[6].Value;
String SubPattern = @"\(([a-z0-9]+);(INTEGER|DECIMAL|STRING);(\d1,3);(YES|NO);(YES|NO);(YES|NO);([a-z0-9]+)\)";
MatchCollection match = Regex.Matches(SubCommand, SubPattern, RegexOptions.IgnoreCase);
if (match.Count != 0)
return true;
我认为没有很好地解释我的问题,但我感谢大家的帮助
【讨论】:
以上是关于如何告诉正则表达式检查整个子字符串?的主要内容,如果未能解决你的问题,请参考以下文章