有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何从Java中的字符串行提取特定术语?

我在从每个字符串行提取术语时遇到了一个严重的问题。更具体地说,我有一个csv格式的文件,实际上不是csv格式(它只将所有术语保存到第[0]行)

下面是数千行字符串中的字符串行示例:

(split()不起作用。!!!)

测试。csv

"31451  CID005319044      15939353      C8H14O3S2      beta-lipoic acid     C1C[S@](=O)S[C@@H]1CCCCC(=O)O "
"12232 COD05374044 23439353  C924O3S2    saponin   CCCC(=O)O "
"9048   CTD042032 23241  C3HO4O3S2 Berberine  [C@@H]1CCCCC(=O)O "

我只想提取位于第5位的“β-硫辛酸”“皂甙”“小檗碱”。 你们可以看到术语之间有很大的空格,所以我说第五位

在这种情况下,如何为每行提取位于第5位的术语

还有一件事:六个术语之间的空格长度并不总是相等的。长度可以是一、二、三、四、五,或者类似的。 因为空格的长度是随机的,所以我不能使用.split()函数。 例如,在第一行中,我得到的是“β-硫辛酸”,而不是“β-硫辛酸”**


共 (3) 个答案

  1. # 1 楼答案

    以下是使用字符串拆分和索引的问题解决方案

    import java.util.ArrayList;
    
    public class StringSplit {
    
        public static void main(String[] args) {
            String[] seperatedStr = null;
            int fourthStrIndex = 0;
            String modifiedStr = null, finalStr = null;
            ArrayList<String> strList = new ArrayList<String>();
            strList.add("31451  CID005319044      15939353      C8H14O3S2    beta-lipoic acid   C1C[S@](=O)S[C@@H]1CCCCC(=O)O ");
            strList.add("12232 COD05374044 23439353   C924O3S2   saponin       CCCC(=O)O ");
            strList.add("9048   CTD042032 23241 C3HO4O3S2  Berberine    [C@@H]1CCCCC(=O)O ");
    
            for (String item: strList) {
                seperatedStr = item.split("\\s+");
                fourthStrIndex = item.indexOf(seperatedStr[3])  + seperatedStr[3].length();
                modifiedStr = item.substring(fourthStrIndex, item.length());
                finalStr = modifiedStr.substring(0, modifiedStr.indexOf(seperatedStr[seperatedStr.length - 1]));
                System.out.println(finalStr.trim());
            }
        }
    }
    

    输出:

    β-硫辛酸

    皂甙

    小檗碱

  2. # 2 楼答案

    如果不是β-硫辛酸,这将是一个相对容易的修复方法

    假设只有空格/制表符/其他空格分隔术语,则可以在空格上拆分

    Pattern whitespace = Pattern.compile("\\s+");
    String[] terms = whitespace.split(line); // Not 100% sure of syntax here...
    // Your desired term should be index 4 of the terms array
    

    虽然这将适用于你的大多数术语,但这也会导致你失去“β-硫辛酸”中的“酸”

    另一个骇客的解决方案是在上面代码生成的数组中添加第6个点的检查,看看它是否匹配英文字母。如果是这样的话,你可以有理由相信第六个点实际上是第五个点的一部分,所以你可以把它们连在一起。不过,如果您与>;=三个字。大概是

    Pattern possibleEnglishWord = Pattern.compile([[a-zA-Z]*); // Can add dashes and such as needed
    if (possibleEnglishWord.matches(line[5])) {
        // return line[4].append(line[5]) or something like that
    }
    

    你可以尝试的另一件事是用一个空格替换所有的空格组,然后删除所有不仅仅由英文字母/破折号组成的空格

    line = whitespace.matcher(line).replaceAll("");
    Pattern notEnglishWord = Pattern.compile("^[a-zA-Z]*"); // The syntax on this is almost certainly wrong
    notEnglishWord.matcher(line).replaceAll("");
    

    希望剩下的就是你要找的术语

    希望这能有所帮助,但我承认这相当复杂。其中一个问题是,非术语词之间似乎只有一个空格,这将愚弄Hirak提出的选项1。。。如果不是这样的话,这个选项应该有效

    哦,顺便说一句,如果你最终这样做了,把模式声明放在任何循环之外。它们只需要创建一次

  3. # 3 楼答案

    选项1:使用弹簧。拆分并检查多个连续空格。如下面的代码所示:

    String s[] = str.split("\\s\\s+");
            for (String string : s) {
                System.out.println(string);
            }
    

    选项2:通过浏览所有字符实现您自己的字符串拆分逻辑。下面的示例代码(此代码只是给出一个想法。我没有测试此代码。)

    public static List<String> getData(String str) {
            List<String> list = new ArrayList<>();
            String s="";
            int count=0;
             for(char c : str.toCharArray()){
                 System.out.println(c);
                    if (c==' '){
                        count++;
                    }else {
                        s = s+c;
                    }
                    if(count>1&&!s.equalsIgnoreCase("")){
                        list.add(s);
                        count=0;
                        s="";
                    }
                }
    
            return list;
        }