java - Java中如何从给定的字符串中提取单词

标签 java

我正在尝试提取所有单词(甚至是旁边带有括号的单词 - 编程语言中的方法/函数)

但是我只能获取第一个单词,而不能获取所有单词。如何遍历与给定正则表达式匹配的所有单词?

这是我尝试过的。我的 String 是我正在阅读的一个文本文件,它看起来像这样。

infile >> name; 

infile >> Id;
cout << name << " " << Id << endl;
hwp = compute_hw_participation (infile);
tests = compute_tests(tests, infile);
totalscore = compute_totalscore (totalscore, infile);

printRecord (name, Id, hwp, tests, totalscore, outfile);
infile >> name; 

return 0;
}

此外,我正在尝试在此 String 中找到方法 方法有

compute_hw_participation(infile)

compute_totalscore(totalscore, infile)

printRecord(name,Id,hwp,tests,totalscore,outfile)//这个方法方法名和括号之间有一个空格,我也需要得到括号(直到最后括号中的)尽管有空格,我怎样才能实现这一点?

这是我尝试过的:

package com.codeingrams.recursion;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author Jananath Banuka
 */
public class Test {

    private static final Pattern p = Pattern.compile(" [^\\s(]+\\([^)]*\\)|\\S+");

    public static void main(String[] args) {
        String text = "\n"
                + "compute_hw_participation(infile) infile >> name; \n"
                + "while(!infile.eof())\n"
                + "{\n"
                + "infile >> Id;\n"
                + "cout << name << \" \" << Id << endl;\n"
                + "hwp = compute_hw_participation (infile);\n"
                + "tests = compute_tests(tests, infile);\n"
                + "totalscore = compute_totalscore (totalscore, infile);\n"
                + "// grade\n"
                + "printRecord (name, Id, hwp, tests, totalscore, outfile);\n"
                + "infile >> name; \n"
                + "}\n"
                + "\n"
                + "return 0;\n"
                + "}\n"
                + "";

        // create matcher for pattern p and given string
        Matcher m = p.matcher(text);        
        // if an occurrence if a pattern was found in a given string...
        if (m.find()) {
            // ...then you can use group() methods.
            System.out.println(m.group(0)); // gives only infile                        
            System.out.println(m.group(1)); //this gives error arrayIndexoutofBound
        }

    }
}

输出:

compute_hw_participation(infile) Error: Exception in thread "main" java.lang.IndexOutOfBoundsException: No group 1 at java.util.regex.Matcher.group(Matcher.java:538) at com.codeingrams.recursion.Test.main(Test.java:44)

最佳答案

您需要一个与函数调用相匹配的模式,即名称、可能是空格、左括号、一些参数和右括号。

查看Javadoc for Pattern您会看到可以在正则表达式中使用的字符类。您需要:

  • 字母或数字或下划线:\w
  • 可能是空格:\s** 表示零到多次
  • 左括号,需要用反斜杠转义,因为它在正则表达式中具有特殊含义:\(
  • 一些(或没有)字符,直到找到右括号:[^)]* [] 创建一个组,^ 是否定,表示除了组中的内容之外的任何内容。
  • 实际的右括号:\)

然后您需要为每个反斜杠添加另一个反斜杠,因为 Java 字符串还使用反斜杠来表示特殊字符,例如 \n

您还需要添加括号来捕获您感兴趣的数据。这也是您必须引用括号来匹配它们的原因 --- 不带引号的括号意味着分组或捕获。

总的正则表达式为(\w+\s*\([^)]*\))

这是完整的程序:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
    public static void main(String[] args) {
        String text = "\n"
                + "compute_hw_participation(infile) infile >> name; \n"
                + "while(!infile.eof())\n"
                + "{\n"
                + "infile >> Id;\n"
                + "cout << name << \" \" << Id << endl;\n"
                + "hwp = compute_hw_participation (infile);\n"
                + "tests = compute_tests(tests, infile);\n"
                + "totalscore = compute_totalscore (totalscore, infile);\n"
                + "// grade\n"
                + "printRecord (name, Id, hwp, tests, totalscore, outfile);\n"
                + "infile >> name; \n"
                + "}\n"
                + "\n"
                + "return 0;\n"
                + "}\n";
        Pattern p = Pattern.compile("(\\w+\\s*\\([^)]*\\))");
        Matcher m = p.matcher(text);
        while (m.find()) {
            System.out.println(m.group());
        }
    }
}

您很快就会看到这种简单方法的局限性:它还认为 while(!infile.eo() 是一个函数,因为它看起来像一个函数调用。代码不知道关于任何可能的语言关键字。另请注意,它不会捕获 while 表达式中的最后一个右括号。这是因为它不计算括号,仅在第一个右括号处停止。正则表达式还具有对注释或字符串一无所知,并且很乐意选择注释掉的代码或字符串,例如 "foo()"

因此,对于您正在处理的语言使用真正的解析器几乎总是更好。

关于java - Java中如何从给定的字符串中提取单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57442634/

相关文章:

java - 是否可以对非映射实体使用 HQL

java - GPS 定位精度问题

java - 我们可以将 DynamoDB Mapper 用于原子计数器(Java)吗?

java - 使用 Mockito 对 Java Play 框架中的服务类进行单元测试

java - 如何使用 Maven 创建跨项目源发布

java - 如何检查所有 JTexFields 是否为空?

java - 通过java中的控制台浏览网页

java - 强制最小 JPanel 大小

java - android中上传文件到php服务器时如何设置字符串参数

java - 将 JavaDStream<String> 转换为 JavaRDD<String>