我一直在尝试创建一个用空格替换制表符元素的程序(假设制表符相当于8个空格,其中一个或多个空格用非空白字符(字母)。
我开始通过以下方式从扫描仪中提取文件中的文本:
try {
reader = new FileReader(file)
} catch (IOException io) {
println("File not found")
}
Scanner scanner = new Scanner(reader);
scanner.usedelimiter("//Z");
String text = Scanner.next();
然后我尝试解析以下面带有ptrn1的标签结尾的文本片段,并用ptrn2提取每个片段的最后一个单词的长度:
Pattern ptrn1 = Pattern.compile(".*\\t, Pattern.DOTALL);
Matcher matcher1 = ptrn1.matcher(text);
String nextPiece = matcher1.group();
println(matcher1.group()); /* gives me the first substring ending with tab*/
但是:
Pattern ptrn2 = Pattern.compile("\\s.*\\t"); /*supposed to capture the last word in the string*/
Matcher matcher2 = ptrn2.matcher(nextPiece);
String lastword = matcher2.group();
最后一行给出了一个错误,因为它显然无法与模式("\\s.\*\\t")
匹配。这最后一个正则表达式有问题,其意图是"任意数量的空格,后跟任意数量的字符,后跟一个制表符。虽然我无法找出它有什么问题。我尝试过("\\s*.+\\t")
,("\\s*.*\\t")
和("\s+.+\\t")
;仍然没有运气。
稍后,根据以下建议,我简化了代码并在其中包含了示例字符串。如下:
import acm.program.*;
import acm.util.*;
import java.util.*;
import java.io.*;
import java.util.regex.*;
public class Untabify extends ConsoleProgram {
public void run(){
String s = "Be plain,\tgood son,\tand homely\tin thy drift.\tRiddling\tconfession\tfinds but riddling\tshrift. ";
Pattern ptrn1 =Pattern.compile(".*?\t", Pattern.DOTALL);
Pattern ptrn2 = Pattern.compile("[^\\s+]\t", Pattern.DOTALL);
String nextPiece;
Matcher matcher1 = ptrn1.matcher(s);
while (matcher1.find()){
nextPiece = matcher1.group();
println(nextPiece);
Matcher matcher2 = ptrn2.matcher(nextPiece);
println(matcher2.group());
}
}
}
程序可变地崩溃,首先是在" println(matcher2.group())&#34 ;;并在下一次运行" public void run()"消息:"调试当前指令指针" (这是什么意思?)。
答案 0 :(得分:1)
您无需双重转义制表符(即\\t
); \t
会很好。 \t
被java String
解析器解释为制表符,并且该制表符被发送到正则表达式解析器,该解析器将其解释为制表符。您可以查看this answer以获取更多信息。
此外,您应该使用Pattern.DOTALL
,而不是Pattern.Dotall
。
答案 1 :(得分:1)
模式"\\s.*\\t"
必须匹配单个空白字符(\s
),后跟0个或多个字符(.*
),后跟单个标签(\t
)。如果要捕获最后一个单词和一个尾随选项卡,则应使用单词boundary escape \b
Pattern.compile("\\b.*\\b\t");
如果您不想匹配任何字符,可以将上面的.
替换为使用\w
或任何字词定义。
这是您用来匹配标签之前的任何字词的代码:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegEx {
public static void main(String args[]) {
String text = "ab cd\t ef gh\t ij";
Pattern pattern = Pattern.compile("\\b(\\w+)\\b\t", Pattern.DOTALL);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println(matcher.group(1));
}
}
}
以上将输出
cd
gh
有关详情,请参阅Regular Expression Tutorial,尤其是Predefined Character Classes和Boundary Matchers部分。
您可以在Regex101上获得更多详细信息并尝试使用此正则表达式。
答案 2 :(得分:1)
查看示例字符串会很有用。如果您只想要标签前的最后一个单词,那么您可以使用:
([^\s]+)\t
注意()
是将最后一个单词放在一个组中。 [^\s]+
表示一个或多个非空格。