|
|
@@ -247,7 +247,14 @@ public class PdfParseService {
|
|
|
parseGutFloraTables(lines, "核心菌属构成表", "核心菌属", gutFlora);
|
|
|
// 解析有害菌属构成表
|
|
|
parseGutFloraTables(lines, "有害菌属构成表", "有害菌", gutFlora);
|
|
|
-
|
|
|
+ // 解析其它重要菌属
|
|
|
+ parseGutFloraTables(lines, "其它重要菌属构成表", "其它重要菌属", gutFlora);
|
|
|
+ // 解析病原菌属
|
|
|
+ parseGutFloraTables(lines, "病原菌属构成表", "病原菌属", gutFlora);
|
|
|
+ // 解析菌群层级表(菌纲/菌目/菌科/菌属/菌种)
|
|
|
+ parseTaxonomyLevels(lines, gutFlora);
|
|
|
+ // 解析主要消化道致病菌
|
|
|
+ parsePathogenicBacteria(lines, indicators);
|
|
|
// 解析益生菌
|
|
|
parseProbioticSection(lines, probioticSpecies);
|
|
|
|
|
|
@@ -311,6 +318,17 @@ public class PdfParseService {
|
|
|
new String[]{"抗生素风险评估", "个体化食物推荐表"},
|
|
|
KNOWN_NEUROTRANSMITTER, "神经递质与激素", indicators);
|
|
|
|
|
|
+ // 主要消化道致病菌(inline格式)
|
|
|
+ parseInlinePathogenicBacteria(fullText, indicators);
|
|
|
+
|
|
|
+ // 菌群表(核心菌属/有害菌属/其它重要菌属/病原菌属/益生菌/层级表)
|
|
|
+ parseGutFloraTables(lines, "核心菌属构成表", "核心菌属", gutFlora);
|
|
|
+ parseGutFloraTables(lines, "有害菌属构成表", "有害菌", gutFlora);
|
|
|
+ parseGutFloraTables(lines, "其它重要菌属构成表", "其它重要菌属", gutFlora);
|
|
|
+ parseGutFloraTables(lines, "病原菌属构成表", "病原菌属", gutFlora);
|
|
|
+ parseTaxonomyLevels(lines, gutFlora);
|
|
|
+ parseProbioticSection(lines, probioticSpecies);
|
|
|
+
|
|
|
result.setDiseaseRisks(diseaseRisks);
|
|
|
result.setGutFlora(gutFlora);
|
|
|
result.setProbioticSpecies(probioticSpecies);
|
|
|
@@ -981,6 +999,149 @@ public class PdfParseService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // ======================== 菌群层级表解析(菌纲/菌目/菌科/菌属/菌种) ========================
|
|
|
+
|
|
|
+ private void parseTaxonomyLevels(List<String> lines, List<ParsedGutFlora> result) {
|
|
|
+ int sectionStart = -1;
|
|
|
+ for (int i = 0; i < lines.size(); i++) {
|
|
|
+ if (lines.get(i).contains("菌群检出详细列表")) {
|
|
|
+ sectionStart = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (sectionStart < 0) return;
|
|
|
+
|
|
|
+ int sectionEnd = lines.size();
|
|
|
+ for (int i = sectionStart + 1; i < lines.size(); i++) {
|
|
|
+ String line = lines.get(i);
|
|
|
+ if (line.contains("个体化食物推荐表") || line.contains("报告总结") || line.contains("健康总分")) {
|
|
|
+ sectionEnd = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ String[][] levels = {{"纲", "菌纲构成"}, {"目", "菌目构成"}, {"科", "菌科构成"}, {"属", "菌属构成"}, {"种", "菌种构成"}};
|
|
|
+
|
|
|
+ for (String[] level : levels) {
|
|
|
+ String levelChar = level[0];
|
|
|
+ String category = level[1];
|
|
|
+
|
|
|
+ int levelStart = -1;
|
|
|
+ for (int i = sectionStart; i < sectionEnd - 2; i++) {
|
|
|
+ if (lines.get(i).equals(levelChar) && lines.get(i + 1).equals("名称") && lines.get(i + 2).contains("丰度")) {
|
|
|
+ levelStart = i + 3;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (levelStart < 0) continue;
|
|
|
+
|
|
|
+ int idx = levelStart;
|
|
|
+ while (idx + 3 < sectionEnd) {
|
|
|
+ String name = lines.get(idx);
|
|
|
+
|
|
|
+ boolean isNextLevel = false;
|
|
|
+ for (String[] l : levels) {
|
|
|
+ if (name.equals(l[0])) { isNextLevel = true; break; }
|
|
|
+ }
|
|
|
+ if (isNextLevel || name.contains("其它重要菌属") || name.contains("病原菌属")
|
|
|
+ || name.contains("核心菌属") || name.contains("有害菌属")
|
|
|
+ || name.contains("菌群检出详细列表")) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (name.equals("名称") || name.contains("丰度") || name.contains("人群") || name.contains("检出")) {
|
|
|
+ idx++; continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ String abundance = lines.get(idx + 1);
|
|
|
+ String popLevel = lines.get(idx + 2);
|
|
|
+ String detRate = lines.get(idx + 3);
|
|
|
+
|
|
|
+ if (abundance.contains("%") || isNumeric(abundance.replaceAll("[^0-9.]", ""))) {
|
|
|
+ ParsedGutFlora flora = new ParsedGutFlora();
|
|
|
+ flora.setBacteriaName(name);
|
|
|
+ flora.setBacteriaValue(cleanNumericValue(abundance));
|
|
|
+ flora.setPopulationLevel(popLevel);
|
|
|
+ flora.setDetectionRate(detRate);
|
|
|
+ flora.setCategory(category);
|
|
|
+ flora.setLevel(levelChar);
|
|
|
+ result.add(flora);
|
|
|
+ idx += 4;
|
|
|
+ } else {
|
|
|
+ idx++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // ======================== 主要消化道致病菌解析 ========================
|
|
|
+
|
|
|
+ private void parsePathogenicBacteria(List<String> lines, List<ParsedIndicator> result) {
|
|
|
+ int startIdx = -1;
|
|
|
+ for (int i = 0; i < lines.size(); i++) {
|
|
|
+ if (lines.get(i).contains("主要消化道致病菌")) {
|
|
|
+ startIdx = i + 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (startIdx < 0) return;
|
|
|
+
|
|
|
+ for (int i = startIdx; i < lines.size() - 2; i += 3) {
|
|
|
+ String name = lines.get(i);
|
|
|
+ String value = lines.get(i + 1);
|
|
|
+ String status = lines.get(i + 2);
|
|
|
+
|
|
|
+ if (name.contains("致病菌") || name.contains("丰度") || name.contains("评估")
|
|
|
+ || name.contains("肠道屏障") || name.contains("抗生素")) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (value.contains("%") || value.equals("ND") || value.equals("0")) {
|
|
|
+ ParsedIndicator ind = new ParsedIndicator();
|
|
|
+ ind.setCategory("主要消化道致病菌");
|
|
|
+ ind.setIndicatorName(name);
|
|
|
+ ind.setIndicatorValue(value);
|
|
|
+ ind.setStatus(status);
|
|
|
+ result.add(ind);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void parseInlinePathogenicBacteria(String fullText, List<ParsedIndicator> result) {
|
|
|
+ int sidx = fullText.indexOf("主要消化道致病菌");
|
|
|
+ if (sidx == -1) return;
|
|
|
+
|
|
|
+ int eidx = fullText.indexOf("肠道屏障", sidx);
|
|
|
+ if (eidx == -1) eidx = fullText.length();
|
|
|
+ String region = fullText.substring(sidx, eidx);
|
|
|
+
|
|
|
+ for (String name : KNOWN_PATHOGENS) {
|
|
|
+ int idx = region.indexOf(name);
|
|
|
+ if (idx == -1) continue;
|
|
|
+
|
|
|
+ String after = region.substring(idx + name.length());
|
|
|
+ java.util.regex.Matcher m = Pattern.compile("(\\d+%)").matcher(after);
|
|
|
+ if (!m.find()) continue;
|
|
|
+
|
|
|
+ String value = m.group(1);
|
|
|
+ int assessmentStart = idx + name.length() + m.group().length();
|
|
|
+ int assessmentEnd = region.length();
|
|
|
+ for (String nextName : KNOWN_PATHOGENS) {
|
|
|
+ if (nextName.equals(name)) continue;
|
|
|
+ int ni = region.indexOf(nextName, assessmentStart);
|
|
|
+ if (ni != -1 && ni < assessmentEnd) assessmentEnd = ni;
|
|
|
+ }
|
|
|
+ String status = region.substring(Math.min(assessmentStart, assessmentEnd), assessmentEnd).trim();
|
|
|
+
|
|
|
+ ParsedIndicator ind = new ParsedIndicator();
|
|
|
+ ind.setCategory("主要消化道致病菌");
|
|
|
+ ind.setIndicatorName(name);
|
|
|
+ ind.setIndicatorValue(value);
|
|
|
+ ind.setStatus(status);
|
|
|
+ result.add(ind);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// ======================== 益生菌解析 ========================
|
|
|
|
|
|
private void parseProbioticSection(List<String> lines, List<ParsedGutFlora> result) {
|