請問下面的這個程式,我ip的第一位提取出來都只有一位數,請問哪位大大可以幫忙解答?
import re
str1 = """TCP source 12.168.189.167:32806 destination 1.78.5.128:65247, idle 0:00:00, bytes 74, flags UIO
TCP source 192.168.189.167:80 destination 137.78.5.128:65233, idle 0:00:03, bytes 334516, flags UIO """
print(str1)
list1 = str1.split('\n')
for x in list1:
result = re.match(
".(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}):(\d{1,5}).(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}):(\d{1,5}).bytes\s+("
"\d+).flags\s+(\w)\s", x).groups()
print(result)
結果會變成這樣
('2.168.189.167', '32806', '1.78.5.128', '65247', '74', 'UIO')
('2.168.189.167', '80', '7.78.5.128', '65233', '334516', 'UIO')
程式碼差一個word就會產生誤會
Regular Expression只要差一個char就會錯
建議先把程式碼用 code block 框起來
比較不會誤會
以下的程式碼
跟你原始的程式碼應該不完全一樣吧
import re
str1 = """TCP source 12.168.189.167:32806 destination 1.78.5.128:65247, idle 0:00:00, bytes 74, flags UIO
TCP source 192.168.189.167:80 destination 137.78.5.128:65233, idle 0:00:03, bytes 334516, flags UIO """
print(str1)
list1 = str1.split('\n')
for x in list1:
result = re.match(
".(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}):(\d{1,5}).(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}):(\d{1,5}).bytes\s+("
"\d+).flags\s+(\w)\s", x).groups()
print(result)
這不是解答
只是建議你修正題目
比較可以節省大家時間
import re
str1 = """TCP source 12.168.189.167:32806 destination 1.78.5.128:65247, idle 0:00:00, bytes 74, flags UIO
TCP source 192.168.189.167:80 destination 137.78.5.128:65233, idle 0:00:03, bytes 334516, flags UIO """
print(re.findall("(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1,5}).+bytes (\d+).+flags (\w+)", str1))
match是從字串開始去找模式,而且只傳回一個,你有辦法找到才有鬼。
了解!我還以為是只有search才回傳一個,但還是有點不太了解用match為何連後面的位數都可以找出來,就偏偏第一位沒辦法? 如上面我的程式碼的結果('2.168.189.167', '32806', '1.78.5.128', '65247', '74', 'UIO')
('2.168.189.167', '80', '7.78.5.128', '65233', '334516', 'UIO')
就第一位的192和137都剩一個,但後面的ip都可以被找出
然後我想請教您後來用findall寫的這個後面漏掉dst ip我把他補上如下,但跑出來的結果變成192有找到了但是137.78.5.128:65223還是只能顯示'7.78.5.128:65233'
print(re.findall("(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1,5}).*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1,5}).+bytes (\d+).+flags (\w+)", str1))
還懇請各位大大的指點
.+source (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1,5}) destination (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1,5}).+bytes (\d+).+flags (\w+)
我用你的code跑不出任何東西...
可以了,無意間試出來了,居然加個\s就有了!!不過還是不懂為何.*沒包含全部居然還要加個\s,難道.*不包含空白?
import re
str1 = """TCP source 12.168.189.167:32806 destination 1.78.5.128:65247, idle 0:00:00, bytes 74, flags UIO
TCP source 192.168.189.167:80 destination 137.78.5.128:65233, idle 0:00:03, bytes 334516, flags UIO """
print(str1)
list1 = str1.split('\n')
dict1 = {}
for x in list1:
result = re.match(
"(.*\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d{1,5}).*\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d{1,5}).*bytes\s+("
"\d+).*flags\s+(\w*)\s*", x).groups()
print(result)
regularExpress裡的 . 是任意字元的意思,跟ip位址裡的小數點是不同意思,你的
\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}
"1234567" 也能通過測試
我建議改成
(\d+)\.(\d+)\.(\d+)\.(\d+)
https://regex101.com/r/nKTnq6/2/
因為999也能過\d{1,3},所以犯不著寫這麼長
字被.* 吃掉了
>>> import re
>>> s = "source 192"
>>> re.match(".*(\d{1,3})",s).groups()
('2',)
>>> re.match(".*(\d{2,3})",s).groups()
('92',)
>>> re.match(".*(\d{3})",s).groups()
('192',)
>>> re.match("\D*(\d{1,3})",s).groups()
('192',)