次のコードスニペットは、入力テキストのすべての大文字のリストを生成します。
grep -o '[^ ]*[[:upper:]][^ ]*' book_text.txt > Capitalized_words.txt
ここで、長さに関係なく、大文字でマークされた固有のフレーズの発生回数を抽出して計算したいと思います。
つまり、大文字の最初の文字を共有するスペースで区切られた単語の一意の文字列数が必要です。提供された唯一のフレーズには、句読点や大文字以外の単語が含まれていないため、2つのフレーズとにUniversity of British Columbia
なります。University
British Columbia
入力例:
Harvard archaeologists in Mexico also participated in the International
School of American Archaeology and Ethnology in Mexico City with scholars from
Mexico, Prussia and the United States.
予想出力:
1 - Harvard
1 - International School
1 - American Archaeology
1 - Ethnology
1 - Mexico City
2 - Mexico
1 - Prussia
1 - United States
例では、とは、Mexico
単語Mexico City
を共有する2つの異なる固有の構文です。
答え1
GNU grep
PCREを使用してビルドする場合は、以下をサポートします。
$ grep -Pow '(\p{Lu}\w*)(\s+(?1))*' input | sort | uniq -c
1 American Archaeology
1 Ethnology
1 Example Input
1 Harvard
1 International School
2 Mexico
1 Mexico City
1 Prussia
1 United States
または:
<input tr -s '[:space:]' '[ *]' |
grep -Pow '(\p{Lu}\w*)(\s+(?1))*' |
sort |
uniq -c
空白文字(改行文字を含む)のすべてのシーケンスは、最初に単一の空白(たとえばExample Input
、Example Input
または)Example\nInput
に変換されます。
-w
該当しないので参考にしてください空間分離単語、単語の境界は単語と単語ではなく文字の間にあります(単語の文字は数字と下線です)。あなたが欲しいと言った? スペースで区切られた単語United States
ただし、これは代わりにまたは代わりUnited States.
にMexico
入力を期待することと矛盾します。Mexico, Prussia
また、[^ ]*[[:upper:]][^ ]*
スペースで区切られた単語と一致します。含む大文字が 1 つ以上ありますが、先頭にある必要はありません。たとえば、fooBar
またはと一致します0xAB+12
。(?<!\S)\p{Lu}\S*
大文字で始まるスペースで区切られた単語が必要です。
$ grep -Po '(?<!\S)(\p{Lu}\S*)(\s+(?1))*' input | sort | uniq -c
1 American Archaeology
1 Ethnology
1 Example Input:
1 International School
1 Mexico
1 Mexico City
1 Mexico, Prussia
1 United States."
(Harvard
全行があり、スペースExample Input: "Havard ..."
で区切られた単語が大文字で始まらないため、欠落しています。)input
"Harvard
in
途中でいくつかを追加することもできます。of
$ grep -Pow '(\p{Lu}\w*)((\s+(in|of))?\s+(?1))*' input | sort | uniq -c
1 Ethnology in Mexico City
1 Example Input
1 Harvard
1 International School of American Archaeology
2 Mexico
1 Prussia
1 United States
\w
英語以外のテキストを扱う場合に置き換えることもできます((?=\w)\X)
。つまり、単語文字、一致単語文字で始まる文字素クラスタ。
$ echo $'Universidad Nacional Auto\u0301noma de Me\u0301xico' |
grep -Pow '(\p{Lu}\w*)((\s+(in|of|de))?\s+(?1))*' | sort | uniq -c
1 Me
1 Universidad Nacional Auto
$ echo $'Universidad Nacional Auto\u0301noma de Me\u0301xico' |
grep -Pow '((?=\p{Lu})\X((?=\w)\X)*)((\s+(in|of|de))?\s+(?1))*' |
sort | uniq -c
1 Universidad Nacional Autónoma de México
Bar
ではまだ一致しています$'foo\u0301Bar'
。
さらに、単語の文字/小文字および/または区切り文字で覆われる名前の構成を具体化する必要があるかもしれません。樹脂の台所、オブライアン小学校、ジャン・ポール・サルトル高校、等。
これらすべてをまとめると、次のように終わります。
first_grapheme='(?: (?= \p{Lu} ) \X )'
word_character="[\w'-]"
word_grapheme="(?: (?= $word_character ) \X )"
word="$first_grapheme $word_grapheme *"
separator='(?: [ ] (?: in | on | of | de | en ) )? [ ]'
<input tr -s '[:space:]' '[ *]' |
grep -Po "(?x) (?<! \pM | $word_character ) $word (?: $separator $word ) *" |
sort |
uniq -c
答え2
Raku(以前のPerl_6)の使用
raku -e '.subst(",", " and ", :g).subst(".", " ", :g).comb(/ <( [ <:Lu> <:Ll>+ \h+ ]+ )> <:Ll>* /).map(*.trim-trailing).Bag.antipairs.join("\n").say for lines();'
入力例:
Harvard archaeologists in Mexico also participated in the International School of American Archaeology and Ethnology in Mexico City with scholars from Mexico, Prussia and the United States.
出力例(最終):
1 Ethnology
1 Prussia
2 Mexico
1 American Archaeology
1 Harvard
1 Mexico City
1 International School
1 United States
興味深い質問は、Rakuがかなり進化した正規表現エンジン(下の参照によるとPCREよりも進化している)と考えられているため、Rakuを使用してこの問題を解決することにしました。
Rakuコードを3つの主要部分に分割することから始めることができます。このcomb
セクションでは、正規表現マッチングを使用してテキスト入力を必須要素に分割します。あなたはすでに多くのシンボル(または概念)に精通しています。たとえば、Rakuのキャプチャタグはです<(…)>
。この部分だけが1を返しましたが、このcomb
部分だけが予想値である8/9を返しました。
raku -e '.comb(/ <( [ <:Lu> <:Ll>+ \h+ ]+ )> <:Ll>* /).join("\n").say for lines();'
出力例(試行#1):
Harvard
Mexico
International School
American Archaeology
Ethnology
Mexico City
Prussia
United
Mexico,
値と部分値の両方がStates.
そのまま残っているため、句読点に対処する必要があることがすぐにわかります。 2回目の試み:
raku -e '.subst(",", " and ", :g).subst(".", " ", :g).comb(/ <( [ <:Lu> <:Ll>+ \h+ ]+ )> <:Ll>* /).join("\n").say for lines();'
出力例(試行#2):
Harvard
Mexico
International School
American Archaeology
Ethnology
Mexico City
Mexico
Prussia
United States
上記は予想値である9/9を返します。最後にコンマを、ピリオドを空白に置き換える,
ことにしました。 (テキストに対する最善の措置を決定する必要があります)。and
.
一番上の最終結果を取得するには、.map(*.trim-trailing).Bag.antipairs
目的の結果を生成するコードに呼び出しを挿入します。
https://slides.yowconference.com/yowwest2015/Conway-EverythingYouKnowAboutRegexesIsWrong.pdf
https://youtu.be/ubvSjW6Nyqk
https://raku.org