文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>1.12 扩展用户输入里面的变量

1.12 扩展用户输入里面的变量

时间:2007-01-05  来源:xiaoshengcaicai

1.12 扩展用户输入里面的变量

1.12.1 问题

你读到了一个内嵌变量引用的字符串,比如:

You owe $debt to me.

你想要把字符串里面的$debt 替换成这个变量对应的值。

1.12.2 解决方案

如果这些内嵌变量是全局变量,可以通过符号引用(symbolic references)来进行替换:

$text =~ s/\$(\w+)/${$1}/g;

如果这些内嵌变量可能是my变量,可以加上/ee这样用:

$text =~ s/(\$\w+)/$1/gee;

1.12.3 讨论

上面说的第一种方法主要是找到一个变量名,然后使用符号反引用(symbolic dereferencing)来把它的内容内插到字符串里面。如果$1包含了这个变量名,那么${$1}就是该变量包含的内容。不过,如果你在程序里面使用了use strict 'refs'这个宏编译指令的话,第一个方法是不行的,因为这个宏编译指令禁止符号反引用(symbolic dereferencing)。

our ($rows, $cols);
no strict 'refs'; # for ${$1}/g below
my $text;

($rows, $cols) = (24, 80);
$text = q(I am $rows high and $cols long); # like single quotes!
$text =~ s/\$(\w+)/${$1}/g;
print $text;
I am 24 high and 80 long

你可能见过/e这个修饰符,在正则替换的时候,使用这个修饰符,替换部分就可以是一段代码而不是一个字符串。它适用于这样的情况:当你不知道应该替换成具体什么值,但是你知道应该怎么计算替换值的时候。举个例子,把字符串里面的每个数字变成2倍:

$text = "I am 17 years old";
$text =~ s/(\d+)/2 * $1/eg;

当Perl在编译你的程序的时候看到了/e,它会提前把这个替换块的代码跟你程序的其他代码一起编译,这个时候这块替换代码还不会执行到。当替换发生的时候,$1被替换成匹配的字符串,然后执行类似这样的代码:

2 * 17

如果我们试着这样写的话:

$text = 'I am $AGE years old'; # note single quotes
$text =~ s/(\$\w+)/$1/eg; # WRONG

假设$text里内嵌了变量$AGE, Perl会很忠诚的把$1换成$AGE,然后执行下面的代码:

'$AGE'

这行代码只是原样返回字符串而已。而我们需要的返回变量里面的内容,为了实现这个,需要再加一个/e:

$text =~ s/(\$\w+)/$1/eeg; # finds my( ) variables

是的,你想加几个/e就加几个。只有第一个/e是要被编译和进行语法检查的。这个就跟eval {BLOCK}差不多,只是它不捕获异常。它跟do {BLOCK}更像吧。

其他接下来的/e修饰符跟第一个是非常不一样的。它们更像eval "STRING"这样的结构。除非执行到了不然是不会编译的。这样有一个小小的好处就是在这块代码里面不再需要使用no strict 'refs'这个宏编译指令了,更大的优点在于,它跟符号反引用(symbolic dereferencing)不一样,这样的方法可以找到那些用my生成的变量,而这是符号反引用做不到的。

下面的例子使用了/x修饰符,使到正则模式匹配部分可以包含空格和评论,使用/e来对替换部分当成代码进行求值。/e 修饰符让我们在非严重型错误发生的时候可以有更好的控制:

# expand variables in $text, but put an error message in
# if the variable isn't defined
$text =~ s{
\$ # find a literal dollar sign
(\w+) # find a "word" and store it in $1
}{
no strict 'refs'; # for $$1 below
if (defined ${$1}) {
${$1}; # expand global variables only
} else {
"[NO VARIABLE: \$$1]"; # error msg
}
}egx;

在很久很久以前,字符串里面的$$1是指${$}1,即变量$$后面再跟一个1。这是很久以前的用法,这样你可以很容易的扩展进程ID变量$$来生成临时文件名。现在$$1是指${$1},也就是$1变量的反引用。我们之前专门写成${$1}只是为了看起来更清楚。

1.12.4 参阅

perlre(1) 和 perlop(1) 里的s///;

Programming Perl 第5章;

perlfunc(1) 和 Programming Perl 第29章的 eval函数;

20.9这一节关于替换的类似应用


相关阅读 更多 +
排行榜 更多 +
试着飞手游下载

试着飞手游下载

休闲益智 下载
血染小镇(功能菜单)中文版下载

血染小镇(功能菜单)中文版下载

飞行射击 下载
泰坦之旅高爆版下载

泰坦之旅高爆版下载

角色扮演 下载