繁体   English   中英

正则表达式用于多个关键字匹配

[英]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”值,它需要与用户名具有相同的条件。

我如何才能改善上述正则表达式?

在这种情况下,您需要将匹配项分开,否则您将无法区分usernamepassword 我建议使用一个正则表达式作为用户名,使用另一个正则表达式作为密码。 接下来,更改正则表达式,使字符类为[^;]+而不是[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 如果在记录中找到任何一个值,该命令将返回一个列表,其中包含相关的关键字( usernamepassword ),后跟该值。 如果找到两个值,则列表将包含两个关键字,每个关键字后跟该值。

该命令通过删除所有换行符,然后在每个分号或等号处分割字符串,将记录转换为键值列表。 检查每个键值对,以查看它们的键是username还是password 以及关键字是否尚未添加到res 如果两个条件都成立,则关键字和值将存储在res 如果在命令末尾任何内容已存储在res ,则返回字典:否则返回None

文档: dictforeachiflistprocreturnsetsplitstring

我认为最简单的方法是

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM