2010-12-26 15 views
1

正規表現を使用して、単語が記号文字で始まるか終わるかを確認するにはどうすればよいか、また記号内のテキストを処理する方法も教えてください。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>?

への変更、それは私を助けて?

おかげ

+0

単語がスペースで始まりまたは終わるとどうなりますか?それは "シンボル"と考えられていますか? – DVK

+0

「ドント」のようなアポストロフィのある単語はどうですか? – Cameron

+0

アポストロフィとダッシュの付いた単語もテキストです。 – aliocee

答えて

3

を試してみてください。違いは、彼/彼のコードは、(質問に与えられた例によると)望ましくない記号の隣に/含まれていないすべての単語の周りにタグを置くということです。

#!/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"; 
} 

これはそれを行うのやや長いったらしい方法として私を打つが、それはより洗練された正規表現を描くよりも速く見えた...

EDIT 1:私は提案された変更が組み込まれている DVK(foreachの代わりにマップを使用)構文の強調表示は以前よりもさらに悪化しています。私はそれが何かをあいまいにしないことを願っています...

+0

ほとんど+1ですが、foreachの代わりに地図を使って熟語1ライナーに分割/ foreach/join全体を変換してください:) – DVK

+0

@ DVK私は地図を使うことを検討しましたが、a)初心者だったので、私は事を分かち合っていれば何が起こっているのが彼女にとって簡単だろうと思っていました。 b)それは夜遅く、これは私にとってはより簡単で迅速でした;)しかし、あなたは正しいです! – canavanin

+0

あなたがうまく動作するようになったら、 'map'のブロック形式を使う必要はありません。 'map modify($ _)、split/\ s + /、$ initial_string;と言うだけです。 – daotoad

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

UPDATE

あなたがあれば、ダッシュやアポストロフィを削除するように見えますあなたは、まず正規表現の前に、あなたは

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

これはまた、 "テキストテキスト"のようなテキストを、シンボルで終わらないものに変更します。 – justintime

+0

justintime - 私はOPに "記号"にスペースを入れることを理解しています - 私は間違っている可能性があります。 – DVK

+0

DASH文字の単語はどうですか?私はテキストとしてそれを考える。 – aliocee

2

これは、標準入力を受け取り、それを処理しません、グローバル(例えば、それらが単語内であるかどうか)、それらを削除したいです標準出力に印刷します。

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

単語のコンセプトに合わせてビットを変更する必要があります。 modifeidを使用して、regexxが複数の行にまたがって配置されるようにしました。

入力はPerlの変数であるならば、私はしかし、わずかな変更で、ここではDVKのアプローチを使用しています

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

テキストテキストと一致しますか? – aliocee

+0

+1が可能ならば 'x'には+2が与えられるでしょう – DVK

関連する問題