如果在Java中从控制台读取正则表达式字符,为什么不需要对其进行转义?
请看以下节目:
使用args。java
import java.util.regex.*;
class UseArgs {
public static void main(String [] args) {
String foo = args[0];
String bar = args[1];
Pattern p = Pattern.compile(foo);
Matcher m = p.matcher(bar);
while(m.find()) {
System.out.print("Found at index: " + m.start() + "\n");
}
}
}
使用控制台。java
import java.util.regex.*;
import java.io.Console;
class UseConsole {
public static void main(String [] args) {
Console console = System.console();
String foo = console.readLine("foo: ");
String bar = console.readLine("bar: ");
Pattern p = Pattern.compile(foo);
Matcher m = p.matcher(bar);
while(m.find()) {
System.out.print("Found at index: " + m.start() + "\n");
}
}
}
因此,为了使用UseArgs,我需要调用以下程序:
MacBook-Pro:~ koraytugay$ java UseArgs \\d 4
Found at index: 0
但是对于UseConsole,请查看我如何不需要转义“任意数字”字符:
MacBook-Pro:~ koraytugay$ java UseConsole
foo: \d
bar: 4
Found at index: 0
行为差异背后的原因是什么?我试过了,但找不到任何文档,当使用控制台读取表达式时,为什么我们不需要退出
# 1 楼答案
当你从命令提示符下“调用”你的程序时,你会向另一个正在运行的程序——你的操作系统的“外壳程序”——提供输入
shell有自己的语法规则。特别是,它们使用反斜杠作为转义字符。因此,要传递给Java程序的输入首先用作shell程序的输入;Java程序将获得shell对该输入的转换输出
除此之外,shell将所有单个反斜杠解释为转义字符,将它们从传递给Java程序(或任何其他程序)的字符串中剥离出来。这就是最终用户在命令行中输入斜杠时必须避开单个斜杠的原因
当您在Java代码中硬编码正则表达式时,也有类似的过程。这一次,编译器使用更严格的规则来剥离反斜杠(与大多数Shell不同,Java错误会在字符串文本中的“散乱”反斜杠上出现,而不是将其丢弃)
相比之下,从控制台读取的输入不会经过任何转换。您的程序是第一个获得输入的程序,因此不需要反斜杠转义
# 2 楼答案
命令行参数首先由shell解释, 在传递到可执行程序之前。 它们受到可变扩展、全球扩展、, 举几个例子。
\
字符在shell中有特殊含义, 所以如果你想传递一个文字\
作为参数的一部分, 你需要像你那样逃离它在程序处理的
stdin
上输入输入时, 中间没有壳来解释这一点。 你的按键应该直接进入输入流。 这就是为什么在这种情况下你不需要逃离他们