我有一个字符串,可能包含由空格分隔的任意数量的单个字母.我正在寻找一个正则表达式(在Perl中),它将删除所有(未知数量)单个字母之间的空格.
例如:
ab c d 应该成为 ab cd
a bcd e f gh 应该成为 a bcd ef gh
a b c 应该成为 abc
和
abc d 应保持不变(因为没有单个字母后跟或前面有一个空格).
谢谢你的任何想法.
您的描述与您的示例不符.在我看来,你想要删除任何空格,即(1)前面有一个字母,前面没有字母,(2)后跟一个字母,后面跟着一个字母.这些条件可以精确表示为嵌套的外观:
/(?<=(?<!\pL)\pL) (?=\pL(?!\pL))/
Run Code Online (Sandbox Code Playgroud)
测试:
use strict;
use warnings;
use Test::Simple tests => 4;
sub clean {
(my $x = shift) =~ s/(?<=(?<!\pL)\pL) (?=\pL(?!\pL))//g;
$x;
}
ok(clean('ab c d') eq 'ab cd');
ok(clean('a bcd e f gh') eq 'a bcd ef gh');
ok(clean('a b c') eq 'abc');
ok(clean('ab c d') eq 'ab cd');
Run Code Online (Sandbox Code Playgroud)
输出:
1..4
ok 1
ok 2
ok 3
ok 4
Run Code Online (Sandbox Code Playgroud)
我假设你真的是指一个空格字符(U + 0020); 如果要匹配任何空格,可能需要用空格替换空格\s+.
您可以使用lookdhead和lookbehind断言执行此操作,如perldoc perlre中所述:
use strict;
use warnings;
use Test::More;
is(tran('ab c d'), 'ab cd');
is(tran('a bcd e f gh'), 'a bcd ef gh');
is(tran('a b c'), 'abc');
is(tran('abc d'), 'abc d');
sub tran
{
my $input = shift;
(my $output = $input) =~ s/(?<![[:lower:]])([[:lower:]]) (?=[[:lower:]])/$1/g;
return $output;
}
done_testing;
Run Code Online (Sandbox Code Playgroud)
注意当前代码在第二个测试用例上失败,因为输出是:
ok 1
not ok 2
# Failed test at test.pl line 7.
# got: 'abcd efgh'
# expected: 'a bcd ef gh'
ok 3
ok 4
1..4
# Looks like you failed 1 test of 4.
Run Code Online (Sandbox Code Playgroud)
我这样离开了,因为你的第二个和第三个例子似乎相互矛盾,关于如何处理领先的单个字符.但是,这个框架应该足以让您尝试不同的前瞻和外观,以获得您正在寻找的确切结果.