我正在尝试提取所有单词(甚至是旁边带有括号的单词 - 编程语言中的方法/函数)
但是我只能获取第一个单词,而不能获取所有单词。如何遍历与给定正则表达式
匹配的所有单词?
这是我尝试过的。我的 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/