如何在perl中使用正则表达式检测符号?

时间:2010-12-26 17:03:35

标签: perl

请问如何使用正则表达式检查单词是否以符号字符开头或结尾,以及如何处理符号中的文本。

示例:

  • (text) or te-xt, or tex't. or text?

    将其更改为

  • (<t>text</t>) or <t>te-xt</t>, or <t>tex't</t>. or <t>text</t>?

帮帮我吗?

由于

3 个答案:

答案 0 :(得分:5)

我认为“单词”是指您示例中的字母数字字符?如果您有一个允许的字符列表,这些字符构成一个有效字,那么这就足够了:

my $string = "x1 .text1; 'text2 \"text3;\"";
$string =~ s/([a-zA-Z0-9]+)/<t>$1<\/t>/g; 
              # Add more to character class [a-zA-Z0-9] if needed
print "$string\n";
# OUTPUT: <t>x1</t> .<t>text1</t>; '<t>text2</t> "<t>text3</t>;"

<强>更新

基于你的例子,你似乎想要删除短划线和撇号,如果你想全局删除它们(例如它们是否在单词内),在第一个正则表达式之前,你做

$string =~ s/['-]//g; 

答案 1 :(得分:3)

我在这里使用DVK的方法,但稍作修改。不同之处在于,她/他的代码也会在不包含符号的所有单词周围放置标签,这不符合(根据问题中给出的示例)。

#!/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建议的更改合并(使用map而不是foreach)。现在,语法高亮显示比以前更糟糕;我希望它不会掩盖任何东西......

答案 2 :(得分:2)

这需要标准输入并将其处理并在标准输出上打印。

    while (<>) {
       s {
           (  [a-zA-z]+  )     # word
           (?= [,.)?] )        # a symbol
         }
         {<t>$1</t>}gx ;
       print ;
    }

您可能需要更改该位以匹配单词的概念。 我使用x modifeid来允许regexx分隔多行。

如果输入是Perl变量,请尝试

         $string =~ s{
           (  [a-zA-z]+  )     # word
           (?= [,.)?] )        # a symbol
         }
         {<t>$1</t>}gx ;