[英]creating a regular expression to parse a file - Java
我有一個要解析的日志文件,格式如下:
225:org.powertac.common.Competition::0::new::game-0
287:org.powertac.common.Competition::0::withSimulationBaseTime::1255132800000
288:org.powertac.common.Competition::0::withTimezoneOffset::-6
288:org.powertac.common.Competition::0::withLatitude::45
289:org.powertac.common.Competition::0::withBootstrapTimeslotCount::336
289:org.powertac.common.Competition::0::withBootstrapDiscardedTimeslots::24
290:org.powertac.common.Competition::0::withMinimumTimeslotCount::1400
290:org.powertac.common.Competition::0::withExpectedTimeslotCount::1440
291:org.powertac.common.Competition::0::withTimeslotLength::60
291:org.powertac.common.Competition::0::withSimulationRate::720
292:org.powertac.common.Competition::0::withTimeslotsOpen::24
292:org.powertac.common.Competition::0::withDeactivateTimeslotsAhead::1
300:org.powertac.du.DefaultBrokerService$LocalBroker::1::new::default broker
300:org.powertac.du.DefaultBrokerService$LocalBroker::1::setLocal::true
2074:org.powertac.common.RandomSeed::2::init::CompetitionControlService::0::game-setup::5354386935242895562
2157:org.powertac.common.TimeService::null::setCurrentTime::2009-10-10T00:00:00.000Z
2197:org.powertac.common.RandomSeed::3::init::AccountingService::0::interest::-8975848432442556652
2206:org.powertac.common.RandomSeed::4::init::TariffMarket::0::fees::-6239716112490883981
2213:org.powertac.common.msg.BrokerAccept::null::new::1
2214:org.powertac.common.msg.BrokerAccept::null::new::1::null
2216:org.powertac.common.RandomSeed::5::init::org.powertac.du.DefaultBrokerService::0::pricing::8741252857248937781
2226:org.powertac.common.TariffSpecification::6::new::1::CONSUMPTION
2231:org.powertac.common.Rate::7::new
2231:org.powertac.common.Rate::7::withValue::-0.5
2232:org.powertac.common.Rate::7::setTariffId::6
模式如下:對於新對象:
<id>:<classname>::<order_of_execution>::<new>::<args>
對於方法調用:
<id>:<classname>::<order_of_execution>::<method_name>::<args>
對於內部類:
<id>:<classname$innerclass>::<order_of_execution>::<method_name or new>::<args>
進行init
調用:
<id>:<classname>::<order_of_execution>::<init>::<args>
我想要一個能夠處理所有情況的正則表達式,並且能夠檢索到案例中所示的每個值。 如果要創建一個新對象,則可以使用Java
的Reflection
API。 因此,例如:
2231:org.powertac.common.Rate::7::new
將被解析為“ 2231”,“ org.powertac.common.Rate”,“ 7”,“ new”,args = {}。 我怎么能想到這樣的正則表達式?
將Matcher
與捕獲組配合使用:
String s = "225:org.powertac.common.Competition::0::new::game-0";
Pattern p = Pattern.compile("([^:]+):([^:]+)::([\\d]+)::([^:]+)::(.+)");
Matcher m = p.matcher(s);
if (m.find()) {
String id = m.group(1);
String className = m.group(2);
int orderOfExecution = Integer.valueOf(m.group(3));
String methodNameOrNew = m.group(4);
String[] arguments = m.group(5).split("::");
}
或者使用java.util.Scanner
將分隔符設置為::?
的更簡單方法::?
:
Scanner scanner = new Scanner(s);
scanner.useDelimiter("::?");
int id = scanner.nextInt();
String className = scanner.next();
int orderOfExecution = scanner.nextInt();
String methodNameOrNew = scanner.next();
scanner.useDelimiter("$").skip("::");
String[] arguments = scanner.next().split("::");
不要試圖將所有這些都推到一個正則表達式中。 為每個模式創建一個正則表達式表達式,並針對每一行,將其與每個正則表達式進行匹配,直到找到匹配的模式。 然后,您可以進行相應的解析。
偽代碼:
for line in file:
if re.match(patNew, line):
parseNew(line)
elif re.match(patMethod, line):
parseMethod(line)
...
與<id>:<classname>::<order_of_execution>::<new>::<args>
匹配的正則表達式如下所示:
([0-9]+):(.*?)::([0-9]+)::(new)(?:::(.*))?
由於這些值是用冒號分隔的,並且本身不能包含冒號,因此不需要轉義或引用,因此您所需要的只是一個簡單的
(.*):(.*)::(.*)::(.*)::(.*)
如果args應該是可選的,請使用
(.*):(.*)::(.*)::([^:]*)(?:::(.*))?
這些值在組1到5中。例如,要確定日志條目是否是構造函數調用,請檢查組4是否等於“ new”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.