在探索正则表达式(也称为RegEx-es)时,有许多人似乎将正则表达式视为圣杯.看起来如此复杂的东西 - 只是必须回答任何问题.他们倾向于认为使用正则表达式可以解决所有问题.
另一方面,也有许多人试图不惜一切代价避免使用正则表达式.他们试图找到解决正则表达式的方法并接受额外的编码只是为了它,即使正则表达式是一个更紧凑的解决方案.
为什么正则表达式被认为是如此有争议?是否存在关于它们如何工作的普遍误解?或者可能是一个普遍的信念,正则表达式通常很慢?
在准确探索Java标识符中允许哪些字符时,我偶然发现了一些非常好奇的东西,似乎几乎肯定是一个bug.
我希望发现Java标识符符合以下要求:它们以具有Unicode属性的字符开头,ID_Start后跟具有该属性的字符,并且ID_Continue为前导下划线和美元符号授予例外.事实证明并非如此,而且我发现与我听说过的普通标识符或其他任何其他想法极为不同.
请考虑以下演示,证明Java标识符中允许使用ASCII ESC字符(八进制033):
$ perl -le 'print qq(public class escape { public static void main(String argv[]) { String var_\033 = "i am escape: \033"; System.out.println(var_\033); }})' > escape.java
$ javac escape.java
$ java escape | cat -v
i am escape: ^[
Run Code Online (Sandbox Code Playgroud)
不过,情况甚至更糟.实际上,几乎无限恶化.甚至允许NULL!还有数千个甚至不是标识符字符的其他代码点.我在Solaris,Linux和运行Darwin的Mac上测试了这一点,并且都给出了相同的结果.
这是一个测试程序,它将显示Java非常不允许作为合法标识符名称的一部分的所有这些意外代码点.
#!/usr/bin/env perl
#
# test-java-idchars - find which bogus code points Java allows in its identifiers
#
# usage: test-java-idchars [low high]
# e.g.: test-java-idchars 0 255
#
# …Run Code Online (Sandbox Code Playgroud) 所以我有两个变量
$x = q(foo);
$y = q(bar);
Run Code Online (Sandbox Code Playgroud)
我的目标是在第三个变量中使用它们,它们之间有下划线即foo_bar.有很多方法可以做到这一点,但我想使用qq
所以
$z = qq($x_$y);
Run Code Online (Sandbox Code Playgroud)
这会产生以下错误
Global symbol "$x_" requires explicit package name at test.pl line 45.
Execution of C:\test.pl aborted due to compilation errors.
Run Code Online (Sandbox Code Playgroud)
所以我不得不使用大括号和变量x来使它工作
$z = qq(${x}_$y);
Run Code Online (Sandbox Code Playgroud)
为什么下划线不起作用qq?在这种情况下,为什么我需要大括号?