【问题标题】:Parsing multi line sentences from a file using regex使用正则表达式从文件中解析多行句子
【发布时间】:2023-03-17 11:45:01
【问题描述】:

对于包含如下语句的文件:

He O O
does O O
, O O
however O O
, O O
have B-MWE_LVC B-MWE_LVC_VERB
an I-MWE_LVC O
affair I-MWE_LVC B-MWE_LVC_NOUN
with O O
Clotho B-NE_PER O
, O O
the O O
youngest O O
aspect O O
of O O
Fate B-NE_MISC B-NE_MISC_SB
. O O

This O O
is O O
both O O
awkward O O
and O O
intriguing O O
to O O
Norton B-NE_PER O
since O O
her O O
past O O
is O O
his O O
future B-SENT_BOUND O
. O O

我想根据标记每个句子结尾的正则表达式模式 (.o o) 提取每个句子。我在下面写了一些代码来解析它,但得到一个错误

线程“主”java.lang.StringIndexOutOfBoundsException 中的异常: 字符串索引超出范围:-1 在 java.lang.String.substring(未知 来源)在 com.gyan.siapp.coref.resolve.test.main(test.java:46)

第 46 行是:builder.append(strLine.substring(0, strLine.indexOf(' ')));

我的代码:

    public static void main(String args[]) {
    StringBuilder builder = new StringBuilder();
    String  folderPath ="C:/Users/Desktop/Data_And_Sentences/wiki50.iob";

    Scanner file = null;
    try
    {
        file = new Scanner(new File(folderPath));
    }
    catch (FileNotFoundException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

        List<String> sentences = new ArrayList<String>();

        String strLine;

        //Read File Line By Line

   Pattern matchExp = Pattern.compile ("(.*?)(. O O)");
        Matcher m = matchExp.matcher(strLine);

        while (file.hasNext())   
        {

            while (!m.find()){
                builder.append(strLine.substring(0, strLine.indexOf(' ')));
                builder.append(" ");
            }

            sentences.add(builder.toString());

            }
            System.out.println(sentences);
           //return sentences;
    }

这是正确的方法吗?我应该使用 String Builder 以外的其他结构来确保足够的内存吗?我的猜测是整个文件被作为一个字符串读取,因此我得到了这个异常。对吗?

【问题讨论】:

  • 不要每次都重新编译模式,你只需要在循环外这样做一次。此外,如果您需要帮助发布完整的堆栈跟踪并指出代码中的哪个语句引发了异常。
  • @JimGarrison 根据您的建议编辑了代码,并提供了完整的错误描述。谢谢。
  • 如果有匹配项,您的意思是要将内容附加到builder 吗?删除! 然后while (m.find()){
  • 强烈建议您在调试器中一次单步执行代码以了解它在做什么。

标签: java regex


【解决方案1】:

我不知道这是否会帮助你。下面的代码产生输出为 -

[他,他做到了,他做到了,,他做到了,但是,他做到了,但是,,他做到了,但是,他做到了,但是,他做到了,但是,,他做到了,但是,与,他但是 , 他 确实 , 然而 , , 他 确实 , 然而 , , 他 确实 , 然而 , 最年轻 , 他 确实 , 然而 , 最年轻, 最年轻的方面, 然而, 与, 最年轻的方面, 他确实, 然而, 最年轻的方面。 ,然而,他确实有,最年轻的一面。 ,然而,他确实有,最年轻的一面。这一点,他却用,最年轻的一面。然而,这是他最年轻的一面。这两者,他确实,但是,与,最年轻的方面。这既尴尬,但他确实与,最小的一面。这既尴尬,而且,他确实,但是,与,最年轻的方面。这既尴尬又耐人寻味,然而,他确实做到了,最年轻的一面。这对他来说既尴尬又有趣,然而,他确实与他最年轻的一面有关。这对他来说既尴尬又有趣,然而,他确实与他最年轻的一面有关。这既尴尬又耐人寻味,因为,然而,他确实与他最年轻的一面有关。这既尴尬又耐人寻味,因为她,然而,却是最年轻的一面。这既尴尬又耐人寻味,因为她的过去,他确实,但是,与,最年轻的一面。这既尴尬又耐人寻味,因为她的过去是,但他确实是最年轻的。这既尴尬又耐人寻味,因为她的过去是他的,然而,他却是最年轻的一面。这既尴尬又耐人寻味,因为她的过去是他的,然而,他却是最年轻的一面。这既尴尬又耐人寻味,因为她的过去是他的。 ]

<code>
  public static void main(String args[]) {
        StringBuilder builder = new StringBuilder();
        String  folderPath ="C:/Users/Desktop/Data_And_Sentences/wiki50.iob";

        Scanner file = null;
        try
        {
            file = new Scanner(new File(folderPath));
        }
        catch (FileNotFoundException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        List<String> sentences = new ArrayList<String>();

        String strLine;
        //String sentence = "";
        //Read File Line By Line
        Pattern matchExp = Pattern.compile ("\\.* O O");
        while (file.hasNext())   
        {

            strLine = file.nextLine();
            System.out.println(strLine);
            Matcher m = matchExp.matcher(strLine);
            if(m.find()) {
                System.out.println(strLine.substring(0, strLine.indexOf(" ")));
                builder.append(strLine.substring(0, strLine.indexOf(" ")));
                builder.append(" ");
            }
        }
        System.out.println(sentences);
        System.out.println(builder.toString());
        //return sentences;
    }
</code>

【讨论】:

  • 请不要发布猜测作为答案。 StackOverflow 的重点是作为 未来 读者的存储库。错误的猜测没有任何好处。
【解决方案2】:

首先,Scanner.next() 默认查找并返回除以“”(空格)的下一个完整标记。因此, strLine 将不包含任何空格,然后 strLine.indexOf(' ') 将返回 -1 并导致异常。 您应该将文件逐行读入一个字符串。然后按您的模式拆分它们。 \n

    StringBuilder input = new StringBuilder();
    while(file.hasNext()) {
        input.append(file.nextLine());
    }
    String[] sentences = input.toString().split("\\.* O O");

【讨论】:

  • 这对我的情况没有帮助,因为我只想包含每行的第一个单词并创建一个句子。我不希望额外的标签和 O O 成为我的输出的一部分。这是我正在寻找的输出“他确实,但是,与 Clotho 有染,Fate 中最年轻的方面。下一句......”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多