3

私は複雑な正規表現が非常に苦手ですが、正しい方向に少しずつ進めていきたいです。後で完全な名前が使用されるときに、イニシャルを削除して一部の著者の名前を解析しようとしています。すべての例外をキャッチする「完璧な」ソリューションはおそらくないことはわかっていますが、「十分な」ソリューションを探しています。

入力例

C S Clive Staples Lewis
T H Terence Hanbury White
R Salvatore
George R R Martin
J R R John Ronald Reuel Tolkien
J K Rowling

理想的な出力

Clive Staples Lewis
Terence Hanbury White
R Salvatore
George R R Martin
John Ronald Reuel Tolkien
J K Rowling

これに沿った何か:$str = preg_replace('#(?:\s+\S{1,2})+\s+#',' ',$str);これは明らかに単一の文字の最初のインスタンスがありませんが、それを変更すると、r salvatore の r と jk rowling の jk が削除されます。

洞察をありがとう。

4

6 に答える 6

2

次のように使用できます。

$str = 'C S Clive Staples Lewis';    
$str = preg_replace('#^([A-Z]\s)+(?=([A-Z]+\s+){2,})#i','',$str); 
echo $str; // Clive Staples Lewis

$str = 'J K Rowling';    
$str = preg_replace('#^([A-Z]\s)+(?=([A-Z]+\s+){2,})#i','',$str); 
echo $str; // J K Rowling
于 2013-10-11T13:28:41.870 に答える
1

次の正規表現を使用できます。

^(?:([A-Z])(?=.*?\1[a-z]+)\s)+

一致します:

^ // from the beginning of the string
(?:  // non-capturing group
    ([A-Z]) // cature uppercase string
    (?=.*?\1[a-z]+) // positive lookahead for the letter captured above followed by multiple lowercase characters
    \s // followed by a space
)+ // multiple times

PHPライブ正規表現の例

于 2013-10-11T14:04:28.613 に答える
1

これを使用できます:

$result = preg_replace('~^(?:[A-Z]\h){2,}~m', '', $str); 

例外を入れたい場合は、それを行うことができます:

$str = <<<LOD
C S Clive Staples Lewis
T H Terence Hanbury White
R Salvatore
George R R Martin
J R R John Ronald Reuel Tolkien
J K Rowling
J F Kennedy
C P E Bach
LOD;

$pattern = <<<'LOD'
~
  # definitions

  (?(DEFINE)
    (?<exceptions>  J \h K \h      Rowling
                  | J \h F \h      Kennedy
                  | C \h P \h E \h Bach
    )
  )

  # pattern

  ^(?!\g<exceptions>)
  (?:[A-Z]\h){2,}
~xm
LOD;

$result = preg_replace($pattern, '', $str);
于 2013-10-11T13:35:20.927 に答える
0

次の正規表現を検討してください...

(?(^(\w\s)+\w{2,}(\s\w{2,}){1,})^(\w\s)+)

于 2013-10-11T13:44:24.290 に答える
0

PHP を使用しているにもかかわらず、言語を指定していません。これは Perl のサンプルです。

use strict;
use warnings;

open my $data_fh, '<', 'Data1.txt' 
    or die "Can't open Data1.txt $!";

while (my $line = <$data_fh>) {
    $line =~ s/\b([A-Z])\b (?=.*?\b\1[A-Z]+\b)//xig; # Match an initial only if there is a word starting with that initial later in the string.
    $line =~ s/^\s*|\s*$//g; #strip leading or trailing space.
    print "$line\n";
}

#OUTPUT
Clive Staples Lewis
Terence Hanbury White
R Salvatore
George R R Martin
John Ronald Reuel Tolkien
J K Rowling
于 2013-10-11T13:50:08.323 に答える