2016-10-28 7 views
2

私は、テキストファイルをループするセクションを持ち、システムユーザーの姓と名を抽出するPerlプログラムを作成しています。ただし、一部のユーザーアカウントでは、ミドルネームまたはミドルネームにピリオドを使用することがあります。たとえば、以下の3つの文字列では、John(名)とSmith(姓)のみに一致させようとしています。 (もしあれば)私は最初のミドルネームを/保存したくない:フルネームと任意のミドルネームを一致させるための正規表現

ジョン・スミス

ジョンA.スミス

ジョン・アンドリュー・スミス

私のような何かをしようとしています:私が読んで、最初の単語(名)を取得し、任意の文字に続いて、オプションのスペース(ミドルネーム)、その後、スペースのフォローを持って

(\w+)(?:\s.*\w)?\s(\w+).* 

最後の単語(姓)によって編集されます。しかし、これは動作していないと私は何か解決策を考え出すことができていない。

ご協力いただきましてありがとうございます。

+4

あなたはいくつかの部分、例の姓からforenameと一部の違いにすることはできませんので、不可能な何かをしようとしている:ジャン・フランソワ・ド・ラ・モット・デ・Chanteracは」、「ブトロス・ブトロス=ガーリを」 "私は、フィールドを区切ってフォームを作成することをお勧めします。 –

+1

見てください:https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/ – Toto

答えて

0

スペースで分割して位置別に分析する必要があるため、splitは簡単です。与えられたパターンで文字列を分割し、得られたリストを返します。行の名前だけを使用すると、オプションの中間部分に関係なく、最初と最後の要素である最初と最後の要素を取得できます。

my ($first, $last) = (split ' ', $line)[0,-1]; 

または

my @name = split ' ', $line; 

my $first = shift @name; 
my $last = pop @name; 

またはライン上の項目

my ($first, $last) = (@name == 2) ? @name : @name[0,2]; 

スペースの上で使用するパターン、' 'が後続することができる場合は、特定の位置を使用することができ、どちらかであります小さな特別な–それは任意の空白の量のためのものであり、(可能な)先頭のスペースも破棄します。スペースのための一般的な正規表現パターンが使用されている場合、先頭のスペースは保持され、最初のエレメントの空の文字列で終わることがあります。 splitを参照してください。

ラインが$_にある場合は、while (<$fh>)で例えば、あなたがsplitデフォルト

my ($first, $last) = (split)[0,-1] 

注意を利用することができるこの種のアプローチはあなたのリストのような名前のために動作しますが、一般的に名を解析することであることはるかに丸められた問題。

-1

ほとんどの場合、動作しないエッジケースがたくさんあります。それは、あなたがあなたのコーパスは、あなたが提供するフォーマットで名前のみで構成され、次のように動作することを確認している場合は、言った:

#!/usr/bin/perl 
my @n = (
    "John Smith", 
    "John A. Smith", 
    "John Andrew Smith", 
); 
foreach my $full_name (@n) { 
    my ($first, $last) = $full_name =~ /^\s*(\S+)\s+(?:\S+\s+)?(\S+)\s*$/; 
    print "'$first' '$last'\n"; 
} 

あなたは完全な名前をキャプチャしたほうが良いだろう、それがすべてだが、レガシーシステムの負荷少なくとも姓はそれ自身で欲しい。たぶん、これは手作業を整理する前にあなたを近づけるでしょう。/ \ sの+ /(あなたがそれを行う場合には、上分割してそれを更新...スプリットを使用している答えについて

my ($first, $last) = $full_name =~ /^\s*(\S+)\s+(?:\S+\s+)*?(\S+)\s*$/; 

また、ミドルネームの任意の番号を削除するには、上記を更新することができます任意の空白)。

+1

"_分割を使用している回答について.../\ s +/_ " - いいえ、それは正確に何をすべきではありません。私は、その答えに書かれているように、 '' 'が何をし、'/\ s +/'が何をするのかを知るために、' split'文書を通して読むことをお勧めします。 – zdim

0

あなたのパターンは、ミドルネームの末尾に単語文字(\wを)期待しているが、あなたの例ジョンA.スミスは、ミドルネームの末尾にドットを持っています。私はあなたの問題を解決する必要がありますミドルネームにスペース以外のものを受け入れるように、このようなパターンを変更します。

(\w+)(?:\s[^\s]+)?\s(\w+).* 
関連する問題