2011-08-13 42 views
0

所以我從遊戲服務器10,000+線消息的這個文件,像這樣:正則表達式匹配出現

23年7月11日8時40分十六秒[INFO] NC:移動違規: wolfman98從yasmp (-90.8,64.0,167.5)至(-90.7,64.0,167.3)距離(0.0,0.0,0.2)

11.07.23 10:57:44 NC:移動違規:AKxiZeroDark (-1228.3,11.2,1098.7)至(-1228.3,11.2,1098.7)距離(0.0,0.0, 0.0)

目前正則表達式的代碼,我是:\d{1,4}\.\d{1},迄今一切都在大膽的匹配:

23年7月11日8點40分十六秒 [信息] NC:移動侵犯:從yasmp wolfman98( - 90.864.0167.5)至( - 90.764.0167.3)距離(0.00.00.2

的Ive無法找到一種方式來獲得,只有說,部分:

(-1228.3,11.2,1098.7)至(-1228.3,11.2,1098.7)

的「距離」字之前,並沒有在一開始的時間戳,並最終取代它落得這樣的:

23年7月11日8時40分一十六秒[INFO] NC:移動違規:從yasmp wolfman98 ( - #,#,#)( - #,#,#)距離(0.0,0.0,0.2 )

23年7月11日10時57分44秒[INFO] NC:移動違規:從yasmp AKxiZeroDark( - #,#,#)( - #,#,#)距離(0.0, 0.0,0.0)

並且有一些額外的信息,數字可以是否定的,範圍從1.0數字到1234.0位,這就是爲什麼我需要再次匹配單詞「距離」之前的幫助。

編輯:甚至,這將是罰款,如果整個事情沒有顯示了:

23年7月11日8時40分16秒] [INFO NC:移動侵犯:從yasmp 距離wolfman98(0.0 ,0.0,0.2)

11.07.23 10:57:44 [信息] NC:移動違規:AKxiZeroDark from yasmp distance(0.0,0.0,0。0)

回答

3

一個相當毛茸茸的看着正則表達式將是\((?:-?\d{1,4}\.\d{1}(?:, |\))){3} to \((?:-?\d{1,4}\.\d{1}(?:, |\))){3}(?= distance)。讓我們稍微分解一下。

它由兩個基團是相同的,以匹配兩組數字在括號中:\((?:-?\d{1,4}\.\d{1}(?:, |\))){3}。正則表達式現在允許在數字前面加上一個可選的-,這使得數字匹配-?\d{1,4}\.\d{1}。在每個數字後面都有一個逗號或一個paren,所以迭代我們需要的數字匹配:(?:, |\))。那整個野獸的前綴是\(以獲得號碼組的開頭字母。該正則表達式重複兩次以獲得兩組數字,中間是to匹配。

的最後一位是一個積極的前瞻,以確保我們能夠匹配那些後跟字distance的組數。這個詞不會被包含在比賽中,但必須在那裏才能匹配正則表達式。

我使用非捕獲組(在(?: ...)東西),因爲我不知道你想用捕獲做什麼。

我反對用perl 5.12.2你的兩個例子日誌文件行嘗試了這一點,它似乎工作。

+0

然後,你可以使用這個正則表達式通過提取現在匹配的數字,用散列替換數字,然後重構日誌行來用哈希替換數字:'perl -ne'/ ^(。*)(\((?: (?:,?\ d {1,4} \。\ d {1}(?:,| \))){3} (?:,| \))){3})(?= distance)(。*)$/&& do {my($ pre,$ no_numbers,$ post)=($ 1,$ 2,$ 3) $ no_numbers =〜s/\ d + \。\ d + /#/ g;打印「$ pre $ no_numbers $ post \ n」; }'' – aparker42

0

你會想從(的打開的順序,對)的距離月底前開始匹配。

的未選中,可待太廣正則表達式可能是:\([-0-9., ]+\) to \([-0-9., ]+\)但可以匹配你不想要的東西。

擴展您的號碼相匹配的正則表達式
+1

您還需要在括號對之間爲它匹配一個空格,即'\([ - 0-9。,] + \)到\ ([-0-9。,] + \)'。 – drf

+0

@drf:謝謝,修正。 – Vatine

0
/(?:\-|\b)\d{1,4}.\d{1}\b(?=.*distance)/ 

匹配你想要的數字(用PHP測試)。

0

聽起來像是perl的工作:

use strict; 
use warnings; 
use ARGV::readonly; 

my $rx = qr/\([0-9,\.\- ]+\)/; 

while (<>) { 
    s/ $rx to $rx(distance $rx\s*)$/$1/; 
    print; 
} 

用法:script.pl input.txt > output.txt

或者作爲一個班輪用更簡單的正則表達式。只需刪除前兩個parens,無論它們包含什麼內容:

perl -pwe 's/ \([^)]+\)//; s/ \([^)]+\)//;' input.txt