我有一个字符串,我想删除一对引号之间出现的任何东西,只需用两个引号替换它。现在我有:
$string =~ s/'.*?'/''/g;
但是,这并不包括字符串中有引号的情况,例如:
$string = "'This is Joe\'s car'";
我希望这是"''"
,但它真的最终成为"''s car'"
无论如何要删除最外面的引号之间的所有内容?谢谢!
答案 0 :(得分:2)
你通过让正则表达式非贪婪来要求它。话说:
$string =~ s/'.*'/''/g;
应该产生预期的结果。
答案 1 :(得分:2)
正如已经说过的,这不是一项微不足道的任务。除非字符串中有明确的黑色滑动表示引号不是平衡对的一部分,否则将无法直接确定平衡对的位置。这需要编写使用单引号背后的英语语言规则来执行此操作,即使这样,也可能会出现边缘情况。
一种可能接近的方法是,如果你使用负向前瞻并查看断言,要求起始引号不要在单词字符之前,并且结尾引号不能跟随一个。但是,即使这个要求也会因多个所有权而失败,如下面脚本中的最后一个例子所示:
use strict;
use warnings;
while (<DATA>) {
chomp(my $src = $_);
chomp(my $test = <DATA>);
$src =~ s/(?<!\w)'(.*?)'(?!\w)/'<$1>'/g;
print ($src eq $test ? 'matches - ' : 'no match - ');
print $src, "\n";
}
__DATA__
This is just a normal sentence.
This is just a normal sentence.
'This is Joe's car'
'<This is Joe's car>'
She said, "He said, 'Hurry up.'"
She said, "He said, '<Hurry up.>'"
This is 'special.' That is also 'special.'
This is '<special.>' That is also '<special.>'
'These are players' cars'
'<These are players' cars>'
答案 2 :(得分:0)
你可以试试这个正则表达式:
$string =~ s/'.*?(?<!\\)'/''/g;
但是这不适用于输入hey 'joe \'car
答案 3 :(得分:0)
您可以尝试使用内置模块Text::Balanced
及其extract_delimited()
功能。在列表上下文中,它返回引号,前缀和提醒之间的文本,因此您可以检查它们并删除要跳过的部分:
#!/usr/bin/env perl
use warnings;
use strict;
use Text::Balanced qw<extract_delimited>;
my $result;
my $string = "Before quotes 'This is Joe\\'s car' After quotes 'Last content' End";
while ( my @r = extract_delimited($string, q|'|, q|[^']*|) ) {
$result .= $r[-1] || '';
if ( ! defined $r[0] ) {
$result .= $r[1];
last
}
else {
$result .= "''";
}
$string = $r[1];
}
printf qq|%s\n|, $result;
请注意,我使用双反斜杠来转义单引号,因为perl
在处理之前会自动转义所有单引号。另请注意,开头的转义单引号,如:
my $string = "Before \\'quotes 'This is Joe\\'s car';
也不起作用。我知道这很奇怪,但它可以在大多数简单的情况下工作。试试吧。
运行测试,如:
perl script.pl
产量:
Before quotes '' After quotes '' End