首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >番石榴分隔符到键值映射,其中包含字符串中的拆分字符

番石榴分隔符到键值映射,其中包含字符串中的拆分字符
EN

Stack Overflow用户
提问于 2017-06-21 18:28:18
回答 4查看 2.1K关注 0票数 0

我正在尝试使用番石榴拆分器来解析日志文件。日志文件如下所示:

代码语言:javascript
复制
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=\"-:-"

我使用这段代码来解析它:

代码语言:javascript
复制
Map<String, String> parserMap;
parserMap = Splitter.onPattern("\\s(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)")
.omitEmptyStrings()
.withKeyValueSeparator(Splitter.onPattern("="))
.split(line);

我的问题是location="= /v1/tXXXX“字段,它在字符串中包含'=‘,而当前的withKeyValueSeperator无法解析它。你能帮我怎样改变模式才能正确地得到所有字段吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-06-21 20:12:37

异常java.lang.IllegalArgumentException: Chunk [location="= /v1/tXXXX"] is not a valid entry是从代码中抛出的,因为keyValueSeparator在块中不止一次发生。您可以调整您的keyValueSeparator,以便只匹配与您的值模式相同的符号。例如:

代码语言:javascript
复制
final String keyPattern = "\\S+";
final String valuePattern = "(\\S+|\"[^\"]*\")";
parserMap = Splitter.onPattern("\\s(?=" + keyPattern + "=" + valuePattern + ")")
        .omitEmptyStrings()
        .withKeyValueSeparator(Splitter.onPattern("=(?=" + valuePattern + ")"))
        .split(line);

请注意,如果您的行中有类似于key="key=value"的内容,这是行不通的。

票数 0
EN

Stack Overflow用户

发布于 2017-06-21 19:33:40

不确定番石榴分配器是如何工作的,但是如果使用常规的PatternMatcher类,可以使用下面的regex来捕获键和值:

代码语言:javascript
复制
([\w-]+?)=(".*?"|\S+)

Regex演示

Java代码

代码语言:javascript
复制
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工作演示:

https://ideone.com/y8b8di

您可以在下面看到匹配信息的示例

代码语言:javascript
复制
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"`
票数 1
EN

Stack Overflow用户

发布于 2020-05-18 09:36:56

limit拆分器上使用withKeyValueSeparator

代码语言:javascript
复制
Splitter.onPattern("\\s(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)")
    .omitEmptyStrings()
    .withKeyValueSeparator(Splitter.on("=").limit(2).trimResults())
    .split(line);

见GitHub问题:https://github.com/google/guava/issues/1900

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44683624

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档