Я использую подход ДВК, но с небольшой модификацией. Разница в том, что ее / его код будет также помещать теги вокруг всех слов, которые не содержат / находятся рядом с символом, что (согласно примеру, приведенному в вопросе) нежелательно.
#!/usr/bin/perl
use strict;
use warnings;
sub modify {
my $input = shift;
my $text_char = 'a-zA-Z0-9\-\''; # characters that are considered text
# if there is no symbol, don't change anything
if ($input =~ /^[a-zA-Z0-9]+$/) {
return $input;
}
else {
$input =~ s/([$text_char]+)/<t>$1<\/t>/g;
return $input;
}
}
my $initial_string = "(text) or te-xt, or tex't. or text?";
my $expected_string = "(<t>text</t>) or <t>te-xt</t>, or <t>tex't</t>. or <t>text</t>?";
# version BEFORE edit 1:
#my @aux;
# take the initial string apart and process it one word at a time
#my @string_list = split/\s+/, $initial_string;
#
#foreach my $string (@string_list) {
# $string = modify($string);
# push @aux, $string;
#}
#
# put the string together again
#my $final_string = join(' ', @aux);
# ************ EDIT 1 version ************
my $final_string = join ' ', map { modify($_) } split/\s+/, $initial_string;
if ($final_string eq $expected_string) {
print "it worked\n";
}
Мне кажется, что это довольно скучный способ, но это казалось быстрее, чем составление более сложного регулярного выражения ...
РЕДАКТИРОВАТЬ 1: Я включил изменения, предложенные DVK (используя карту вместо foreach). Теперь подсветка синтаксиса выглядит еще хуже, чем раньше; Надеюсь, это ничего не заслоняет ...