package com.walker.spider; import com.walker.infrastructure.utils.KeyValue; import com.walker.infrastructure.utils.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * 可以解析出key、value形式的数据解析器。 * @author 时克英 * @date 2023-04-26 */ public class KeyValueParse implements TextParse>, List>{ protected final transient Logger logger = LoggerFactory.getLogger(getClass()); @Override public String getDelimiter() { return null; } @Override public List> parse(Object content, List option) { if(content == null || StringUtils.isEmpty(content.toString())){ throw new IllegalArgumentException("content is required!"); } String data = content.toString().trim(); String[] rows = data.split(this.delimiter); logger.debug("分隔后共有 {} 行", rows.length); List> resultList = new ArrayList<>(); String[] keyValueStr = null; for(String text : rows){ text = text.trim(); if(StringUtils.isEmpty(text) || text.equals(this.delimiter)){ logger.warn("存在空行,或只有分隔符:{}", this.delimiter); continue; } // 可能存在多个分隔符,例如:用户冒号分隔,但内容存在类似(http://) if(text.indexOf(StringUtils.NAME_HTTP) > 0 || text.indexOf(StringUtils.NAME_HTTPS) > 0){ // 存在http有多个冒号,需要先找出开头的key String key = this.findKeyWithHttps(option, text); if(StringUtils.isEmpty(key)){ logger.error("行数据没有找到有效 key,row = {}", text); continue; } String value = text.replaceFirst(key + StringUtils.SEPARATOR_COLON, StringUtils.EMPTY_STRING).trim(); keyValueStr = new String[]{key, value}; } else { // 普通行 keyValueStr = text.trim().split(StringUtils.SEPARATOR_COLON); } if(keyValueStr.length == 1){ logger.debug("该行只有一个值,可能没有value,key = {}", keyValueStr[0]); resultList.add(new KeyValue<>(keyValueStr[0], StringUtils.EMPTY_STRING)); } else if(keyValueStr.length == 2){ resultList.add(new KeyValue<>(keyValueStr[0], keyValueStr[1].trim())); } else { logger.error("数据行错误:{}", text); } } if(option != null){ // for(KeyValue kv : resultList){ KeyValue kv = null; for(Iterator> it = resultList.iterator(); it.hasNext();){ kv = it.next(); if(option.contains(kv.getKey())){ logger.debug("包含要的数据,key={}, value={}", kv.getKey(), kv.getValue()); } else { it.remove(); } } } return resultList; } private String findKeyWithHttps(List option, String row){ for(String key : option){ if(row.indexOf(key + StringUtils.SEPARATOR_COLON) >= 0){ logger.debug("找到了 key = {}", key); return key; } } return null; } public void setDelimiter(String delimiter) { this.delimiter = delimiter; } private String delimiter; }