在尝试使用正则表达式验证SQL Server的连接字符串模式时,我取得了以下结果:
^(?!.*?(?<=^|;)[a-zA-Z]+( [a-zA-Z]+)*(=[^;]+?=[^;]*)?(;|$))+([a-zA-Z]+( [a-zA-Z]+)*=[^;]+;?)+$
使用的示例字符串为:
option=value;missingvalue;multiple assignment=123=456
* (在正则表达式 101 中托管和测试)
而且,正如预期的那样,字符串不匹配。问题是我认为这可能不是标准的、推荐的或最佳的正则表达式实现——尤其是在负面的展望部分,考虑到即使在成功匹配之后,它也只是遍历整个字符串。
我将尝试在下面分解它的工作原理:
<小时 />负面展望
1. ^(?!.*?(?<=^|;)
从字符串开头开始或递归贯穿分号字符之后的负前瞻模式
2. [a-zA-Z]+( [a-zA-Z]+)*(=[^;]+?=[^;]*)?(;|$))+
匹配简单或复合选项名称 — 即,仅[a-zA-Z]+
(必需)或另外( [a-zA-Z]+)*
任意次数;之后,当任何给定选项有多个连续值分配时,有一个可选组尝试匹配;最后它以;
或$
(字符串末尾)结尾 — 如果是第一个, 前瞻模式从头开始重新启动(递归)
常规模式匹配
([a-zA-Z]+( [a-zA-Z]+)*=[^;]+;?)+$
这里没有什么新东西要说,除了这是在初始负面展望彻底扫描/验证后实际上应该与字符串匹配的模式。
我不能否认它有点符合我的意图,但我无法抑制我对正则表达式工作原理误解的感觉。
有没有更简单的方法可以做到这一点,同时避免多次使用上述模式递归地向前看?
编辑:根据要求,一些更接近现实生活的示例如下 - 对于有效和无效的格式:
- 有效
Database=somedb;Username=admin;Password=P@ssword!23;Port=1433
- 无效
- 用户名和密码选项之间缺少分隔符
Database=somedb;Username=adminPassword=P@ssword!23;Port=1433
- 端口选项缺少值
Database=somedb;Port;Username=admin;Password=P@ssword!23
以下字符串仅接受名称的字母。 为了进行测试,它接受除值中的等于和分号之外的任何字符。这需要定义为行尾等字符,并且需要排除制表符。 我们有一个负面的展望,禁止在值中使用第二个等号,而有一个消极的回溯,禁止在结束之前使用分号。请注意,您的"正确"示例被发现是错误的,因为末尾没有分号 如果我们尝试阻止另一轮,则无法匹配正则表达式.
我在名称中添加了一个可选的单个空格以匹配"连接超时"和类似内容
/^(s*[a-zA-Z]+ ?[a-zA-Z]+=[^=;]+;)+$/gm
我还允许在 name.
我们的字符串由^
行首(
startgroups*
name[a-zA-Z]+ ?[a-zA-Z]+
名称,在可选空格前后至少包含一个字母。这意味着至少有两个字母=
一个等号(
开始内部组(?!=)
负数 展望等号[^=;]
除等号和分号以外的任何字符至少一次;
文字分号.){4,}
关闭外部组并重复至少 4 次$
行尾
谢谢卡西米尔和伊波利特的改进。我在问题之后使用了前瞻和回溯,但您的语法要干净得多。