Regex 在Perl正则表达式中嵌入求值

Regex 在Perl正则表达式中嵌入求值,regex,perl,Regex,Perl,因此,我正在编写一个快速的perl脚本,它将清理一些HTML代码,并通过HTML->pdf程序运行它。我希望丢失尽可能少的信息,所以我想扩展我的文本区域,以适应它们当前包含的所有文本。这意味着,在我的例子中,将行数设置为基于文本框中字符串的值的计算值 这是我目前使用的正则表达式 $file=~s/<textarea rows="(.+?)"(.*?)>(.*?)<\/textarea>/<textarea rows="(?{ length($3)/80 })"$2&

因此,我正在编写一个快速的perl脚本,它将清理一些HTML代码,并通过HTML->pdf程序运行它。我希望丢失尽可能少的信息,所以我想扩展我的文本区域,以适应它们当前包含的所有文本。这意味着,在我的例子中,将行数设置为基于文本框中字符串的值的计算值

这是我目前使用的正则表达式

$file=~s/<textarea rows="(.+?)"(.*?)>(.*?)<\/textarea>/<textarea rows="(?{ length($3)/80 })"$2>$3<\/textarea>/gis;
$file=~s/(.*)/$3/gis;
不幸的是,Perl似乎没有意识到我被告知的是将Perl代码嵌入搜索和替换正则表达式的语法 有没有Perl迷愿意告诉我我做错了什么? 当做
扎克

我相信你的问题是一个无法逃避的问题

如果这不是问题,那肯定是个问题

试试这个,注意
\/80

$file=~s/<textarea rows="(.+?)"(.*?)>(.*?)<\/textarea>/<textarea rows="(?{ length($3)\/80 })"$2>$3<\/textarea>/gis;

gis
是我必须查找的选项。我认为g=global,I=不区分大小写,s=现在我想不起来了。

这必须用regex完成吗?用正则表达式解析任何标记语言(甚至CSV)都充满了错误。如果可以,请尝试使用标准库:

否则你就要冒着克图鲁报复的风险:

(是的,本文为一些简单的字符串操作留出了空间,因此我认为您的灵魂是安全的。:-

模式是在匹配端执行代码的实验特性,但您希望在替换端执行代码。使用
/e
正则表达式开关:

#! /usr/bin/perl

use warnings;
use strict;

use POSIX qw/ ceil /;

while (<DATA>) {
  s[<textarea rows="(.+?)"(.*?)>(.*?)</textarea>] {
    my $rows = ceil(length($3) / 80);
    qq[<textarea rows="$rows"$2>$3</textarea>];
  }egis;
  print;
}

__DATA__
<textarea rows="123" bar="baz">howdy</textarea>
#/usr/bin/perl
使用警告;
严格使用;
使用POSIX qw/ceil/;
而(){
s[(.*)]{
my$rows=ceil(长度($3)/80);
qq[$3];
}egis;
印刷品;
}
__资料__
你好
输出:

<textarea rows="1" bar="baz">howdy</textarea>
howdy用于嵌入代码的语法仅在替换的“匹配”部分(左侧)有效。要在右侧嵌入代码(这是一个普通的Perl双引号字符串),可以执行以下操作:

$file =~ s{<textarea rows="(.+?)"(.*?)>(.*?)</textarea>}
          {<textarea rows="@{[ length($3)/80 ]}"$2>$3</textarea>}gis;

注意,在这两个示例中,正则表达式的结构都是
s{}{}
。这不仅消除了转义斜杠的需要,而且还允许将表达式分散到多行以提高可读性。

首先,需要在替换文本中引用表达式内部的
/
(否则perl将看到一个s///运算符,后跟数字
80
,依此类推)。或者您可以使用不同的分隔符;对于复杂的替换,匹配括号是一个好主意

然后你会遇到一个主要的问题,
(?{…})
只在模式中可用。替换文本不是一个模式,它(几乎)是一个普通字符串

相反,在
s//
操作符中有
e
修饰符,它允许您编写替换表达式而不是替换字符串

$file =~ s(<textarea rows="(.+?)"(.*?)>(.*?)</textarea>) ("<textarea rows=\"" . (length($3)/80) . "\"$2>$3</textarea>")egis; $file=~s((.*)) (“$3”)EGI; 根据,这可以通过“评估修饰符
s///e
”实现,例如,您的
gis
中必须有一个额外的
e

求值修饰符s///e在替换字符串周围包装一个eval{…},并用求值结果替换匹配的子字符串。一些例子:

# convert percentage to decimal
$x = "A 39% hit rate";
$x =~ s!(\d+)%!$1/100!e;       # $x contains "A 0.39 hit rate"

但是您的示例没有使用您提到的
/e
选项;此外,它是一个完整的perl脚本,而不是一行代码来替换。@您好,是的,它确实使用了/e选项。。。“egis”打开e、g、i和s标志。而且OP也没有要求一艘班轮。。。Greg提供了一个可读的完整perl脚本,可以运行。。。他本可以将模式匹配压缩为一行,就像原稿一样,但这会使它毫无意义地难以理解。你能详细介绍一下你的
@{[perl_code]}
习惯用法吗?当我试图在替换端运行
@{[print(“hello”)]}
时,我没有得到“hello”这个词来代替它。 $file =~ s(<textarea rows="(.+?)"(.*?)>(.*?)</textarea>) ("<textarea rows=\"" . (length($3)/80) . "\"$2>$3</textarea>")egis;
# convert percentage to decimal
$x = "A 39% hit rate";
$x =~ s!(\d+)%!$1/100!e;       # $x contains "A 0.39 hit rate"