Java中从日志行提取大括号值的键值对并封装为指定Java对象
Solution to Parse Custom Log Lines into Java Object
I’ve tackled similar log parsing challenges before, and here’s a straightforward, robust approach to solve your problem:
Step 1: Define the Target Java Class
First, create a class to encapsulate your parsed result—it’ll hold both the log type and the full field-value map:
import java.util.HashMap; import java.util.Map; public class ParsedLogEntry { private final String logType; private final Map<String, String> fields; // Use defensive copying to prevent external modification of the map public ParsedLogEntry(String logType, Map<String, String> fields) { this.logType = logType; this.fields = new HashMap<>(fields); } // Getters only (keeps the object immutable for safety) public String getLogType() { return logType; } public Map<String, String> getFields() { return new HashMap<>(fields); // Return a copy to avoid external changes } @Override public String toString() { return "ParsedLogEntry{" + "logType='" + logType + '\'' + ", fields=" + fields + '}'; } }
Step 2: Build the Log Parser
Use regular expressions to extract all key-value pairs from the log line, then isolate the LOG_TYPE value as the log entry’s type:
import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class LogParser { // Regex to match patterns like "Key {Value}" (handles spaces around braces) private static final Pattern KEY_VALUE_PATTERN = Pattern.compile("(\\w+)\\s*\\{([^}]+)\\}"); public ParsedLogEntry parseLogLine(String logLine) { Map<String, String> allFields = new HashMap<>(); Matcher matcher = KEY_VALUE_PATTERN.matcher(logLine); // Extract every key-value pair from the log line while (matcher.find()) { String key = matcher.group(1).trim(); String value = matcher.group(2).trim(); allFields.put(key, value); } // Pull out the LOG_TYPE and remove it from the fields map String logType = allFields.remove("LOG_TYPE"); if (logType == null) { throw new IllegalArgumentException("Log line missing required LOG_TYPE field: " + logLine); } return new ParsedLogEntry(logType, allFields); } // Test with your sample log line public static void main(String[] args) { String sampleLog = "Level {INFO} field1 {value1} field2 {value2} field3 {value3} field4 {value4} LOG_TYPE {USER_ACTION} field5 {value5} field6 {value6} field7 {value7}"; LogParser parser = new LogParser(); ParsedLogEntry result = parser.parseLogLine(sampleLog); System.out.println("Parsed Log Type: " + result.getLogType()); System.out.println("Parsed Fields: " + result.getFields()); } }
How It Works
- Regex Matching: The pattern
(\w+)\s*\ {([^}]+)\}captures every key-value pair where the key is a word character (letters, numbers, underscores) and the value is any text inside curly braces (note: this assumes values won’t contain nested}—adjust the regex if you need to handle that edge case). - Log Type Isolation: After collecting all fields, we remove the
LOG_TYPEentry from the map and use its value as the log entry’s type. - Immutability: The
ParsedLogEntryclass is designed to be immutable (no setters, defensive copying of the map) to avoid unintended side effects after parsing.
Edge Cases Handled
- Throws a clear exception if the log line doesn’t include
LOG_TYPE - Handles values with spaces (e.g.,
message {User logged in successfully}) - Prevents external code from modifying the parsed fields via defensive copying
内容的提问来源于stack exchange,提问作者pbajpai
相关产品推荐
相关产品推荐

