[英]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.