Как я могу обнаружить символы, используя регулярные выражения в Perl? - PullRequest
1 голос
/ 26 декабря 2010

Пожалуйста, как я могу использовать регулярное выражение, чтобы проверить, начинается или заканчивается ли слово символом, а также как мне обработать текст внутри символа.

Пример:

  • (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 ]

5 голосов
/ 26 декабря 2010

Я предполагаю, что слово означает буквенно-цифровые символы из вашего примера? Если у вас есть список разрешенных символов, которые составляют допустимое слово, то этого достаточно:

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>;"

UPDATE

Исходя из вашего примера, вы, кажется, хотите УДАЛИТЬ тире и апострофы, если хотите удалить их глобально (например, находятся ли они внутри слова или нет), перед первым регулярным выражением вы делаете

$string =~ s/['-]//g; 
3 голосов
/ 27 декабря 2010

Я использую подход ДВК, но с небольшой модификацией. Разница в том, что ее / его код будет также помещать теги вокруг всех слов, которые не содержат / находятся рядом с символом, что (согласно примеру, приведенному в вопросе) нежелательно.

#!/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). Теперь подсветка синтаксиса выглядит еще хуже, чем раньше; Надеюсь, это ничего не заслоняет ...

2 голосов
/ 26 декабря 2010

Он принимает стандартный ввод, обрабатывает его и печатает на стандартном выводе.

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

Возможно, вам придется изменить бит, чтобы соответствовать понятию слова. Я использовал x modifeid, чтобы регулярное выражение могло быть разделено более чем на одну строку.

Если входные данные находятся в переменной Perl, попробуйте

         $string =~ s{
           (  [a-zA-z]+  )     # word
           (?= [,.)?] )        # a symbol
         }
         {<t>$1</t>}gx ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...