我正在尝试使用番石榴拆分器来解析日志文件。日志文件如下所示:
appName=XXX clientIp=X.X.X timestamp="2017-06-05T13:22:12-07:00" request="POST /forward HTTP/1.1" statusCode=204 bytesOut=1167 totalTime=0.062 bytesIn=1289 sourceHost=XXXX connId=49936598 connReqs=9 upInstance=XXX:104:XXX-XXX:8664:17F34 upConnectSec=0.052 upAddr="XX.XX.XX:123" upHost="vcv08it-cvcv2801:8464" upHdrTimeSec=0.058 upRespTimeSec=0.058 pid=32561 upStatusCode=204 message="Access Log" corrKey=GMIFCDIKRZR2T4VZQXJA2IT6 upCached=- length=0 partition=XXX location="= /v1/tXXXX" xff="XX.XX.XX.XX" referer="-" user-agent="Apache-HttpAsyncClient/4.1.1 (Java/1.8.0_131)\" rateLimitCurrentValues="--" rateLimitTimeMs=\"-:-"我使用这段代码来解析它:
Map<String, String> parserMap;
parserMap = Splitter.onPattern("\\s(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)")
.omitEmptyStrings()
.withKeyValueSeparator(Splitter.onPattern("="))
.split(line);我的问题是location="= /v1/tXXXX“字段,它在字符串中包含'=‘,而当前的withKeyValueSeperator无法解析它。你能帮我怎样改变模式才能正确地得到所有字段吗?
发布于 2017-06-21 20:12:37
异常java.lang.IllegalArgumentException: Chunk [location="= /v1/tXXXX"] is not a valid entry是从代码中抛出的,因为keyValueSeparator在块中不止一次发生。您可以调整您的keyValueSeparator,以便只匹配与您的值模式相同的符号。例如:
final String keyPattern = "\\S+";
final String valuePattern = "(\\S+|\"[^\"]*\")";
parserMap = Splitter.onPattern("\\s(?=" + keyPattern + "=" + valuePattern + ")")
.omitEmptyStrings()
.withKeyValueSeparator(Splitter.onPattern("=(?=" + valuePattern + ")"))
.split(line);请注意,如果您的行中有类似于key="key=value"的内容,这是行不通的。
发布于 2017-06-21 19:33:40
不确定番石榴分配器是如何工作的,但是如果使用常规的Pattern和Matcher类,可以使用下面的regex来捕获键和值:
([\w-]+?)=(".*?"|\S+)Java代码
String text = "your string";
Pattern pattern = Pattern.compile("([\\w-]+?)=(\".*?\"|\\S+)");
Matcher m = pattern.matcher(text);
Map<String, String> parserMap = new HashMap<>();
while (m.find()) {
String key = m.group(1);
String value = m.group(2);
parserMap.put(key, value);
}在这里准备了一个IdeOne java工作演示:
您可以在下面看到匹配信息的示例
Match 1
Group 1. 0-7 `appName`
Group 2. 8-11 `XXX`
Match 2
Group 1. 12-20 `clientIp`
Group 2. 21-26 `X.X.X`
Match 3
Group 1. 27-36 `timestamp`
Group 2. 37-64 `"2017-06-05T13:22:12-07:00"`
Match 4
Group 1. 65-72 `request`
Group 2. 73-97 `"POST /forward HTTP/1.1"`发布于 2020-05-18 09:36:56
在limit拆分器上使用withKeyValueSeparator
Splitter.onPattern("\\s(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)")
.omitEmptyStrings()
.withKeyValueSeparator(Splitter.on("=").limit(2).trimResults())
.split(line);https://stackoverflow.com/questions/44683624
复制相似问题