簡體   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