[英]Regexp for multiple keywords matching
我有以下情况,我需要从以username=xxx;
开头的字符串中获取用户名和密码username=xxx;
和password=yyy;
用户名或密码没有限制,除了;
应该是每个关键字的分隔符,并且username始终跟随username=
,password始终跟随password=
。
我试图构造以下内容,但我只得到了部分想要的结果
set value "colour=blue;
age=25;
name=anthony;
username=firstuser;
username=hisuser;
password=test123"
set value2 "colour=blue;
age=25;
name=brothersofanthony;
username=seconduser;
password=test123;"
set value3 "username=user-3"
set value4 "username=user4"
regexp -nocase -- {\y(?:username=|password=)[a-z0-9]+} $value match match2
puts "value is $match and match2 is $match2"
regexp -nocase -- {\y(?:username=|password=)[a-z0-9]+} $value2 match match2
puts "value 2 is $match and match2 is $match2"
regexp -nocase -- {\y(?:username=|password=)[a-z0-9]+} $value3 match match2
puts "value 3 is $match and match2 is $match2"
regexp -nocase -- {\y(?:username=|password=)[a-z0-9]+} $value4 match match2
puts "value 4 is $match and match2 is $match2"
我正在尝试建立一个可以返回我用户名和密码的正则表达式。 使用上面的正则表达式,如果用户名具有[a-z0-9]
,那么我设法仅获得具有正确结果的“用户名”,而实际上它也可以是不同的符号(除了;
因为它是分隔符)
如果发现字符串中多次出现(例如,对于value
,有两个用户名,则应考虑第一个用户名)
上面的regexp的第二个问题是它不显示“ Password”值,它需要与用户名具有相同的条件。
我如何才能改善上述正则表达式?
在这种情况下,您需要将匹配项分开,否则您将无法区分username
或password
。 我建议使用一个正则表达式作为用户名,使用另一个正则表达式作为密码。 接下来,更改正则表达式,使字符类为[^;]+
而不是[a-z0-9]+
以匹配除;
之外的所有字符;
。
set value "colour=blue;
age=25;
name=anthony;
username=firstuser;
username=hisuser;
password=test123"
regexp -nocase -- {\yusername=([^;]+)} $value - username
regexp -nocase -- {\ypassword=([^;]+)} $value - password
puts $username
puts $password
# => firstuser
# => test123
像往常一样,正则表达式实际上比需要的工作更多。
proc getUsernameAndPassword record {
set res [dict create]
foreach {keyword value} [split [string map [list \n {}] $record] \;=] {
if {$keyword in {username password} && $keyword ni [dict keys $res]} {
dict set res $keyword $value
}
}
if {[dict size $res]} {
return $res
} else {
return None
}
}
如果在记录中找不到用户名或密码,此命令将返回字符串None
。 如果在记录中找到任何一个值,该命令将返回一个列表,其中包含相关的关键字( username
或password
),后跟该值。 如果找到两个值,则列表将包含两个关键字,每个关键字后跟该值。
该命令通过删除所有换行符,然后在每个分号或等号处分割字符串,将记录转换为键值列表。 检查每个键值对,以查看它们的键是username
还是password
以及关键字是否尚未添加到res
。 如果两个条件都成立,则关键字和值将存储在res
。 如果在命令末尾任何内容已存储在res
,则返回字典:否则返回None
。
文档: dict , foreach , if , list , proc , return , set , split , string
我认为最简单的方法是
set RE {^(username|password)=(.+?)(?:;|$)}
foreach {matched field contents} [regexp -all -inline -line $RE $value] {
puts "I found '$field' which held '$contents'"
}
在您的第一个样本上,将产生:
I found 'username' which held 'firstuser' I found 'username' which held 'hisuser' I found 'password' which held 'test123'
我们使用-all
来匹配每个可能的位置,而不仅仅是第一个, -inline
来获取返回的匹配项(以便我们可以foreach
它们),以及-line
来使RE引擎不匹配行上的所有内容(影响.
, ^
和$
)。
您必须决定当一个字段出现两次时该怎么做,但这不再像解析为一个更高级别的概念那样匹配 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.