1

私はそのようなCSVファイルを持っています:

"","LESCHELLES","","LESCHELLES"
"","SAINTE CROIX DE VERDON","","SAINTE CROIX DE VERDON"
"","SERRE CHEVALIER","","SERRE CHEVALIER"
"","SAINT JUST D'ARDECHE","","SAINT JUST D'ARDECHE"
"","NEUVILLE SUR VANNES","","NEUVILLE SUR VANNES"
"","ESCUEILLENS ET SAINT JUST","","ESCUEILLENS ET SAINT JUST"
"","PAS DES LANCIERS","","PAS DES LANCIERS"
"","PLAN DE CAMPAGNE","","PLAN DE CAMPAGNE"

そして、私はそれをこのように変換したいと思います:

"","Leschelles","","LESCHELLES"
"","Sainte Croix De Verdon","","SAINTE CROIX DE VERDON","STE CROIX DE VERDON","93"
"","Serre Chevalier","","SERRE CHEVALIER","SERRE CHEVALIER","93"
"","Saint Just D'Ardeche","","SAINT JUST D'ARDECHE"
"","Neuville Sur Vannes","","NEUVILLE SUR VANNES"
"","Escueillens Et Saint Just","","ESCUEILLENS ET SAINT JUST","ESCUEILLENS ET ST JUST","91"
"","Luc","","LUC"
"","Pas Des Lanciers","","PAS DES LANCIERS","PAS DES LANCIERS","93"
"","Plan De Campagne","","PLAN DE CAMPAGNE","PLAN DE CAMPAGNE","93"

これはいいでしょう。deさらに良いこと: 、d'etsurなどの「全体」の単語はすべて小文字にしdesます。これにより、次のようになります。

"","Leschelles","","LESCHELLES"
"","Sainte Croix de Verdon","","SAINTE CROIX DE VERDON","STE CROIX DE VERDON","93"
"","Serre Chevalier","","SERRE CHEVALIER","SERRE CHEVALIER","93"
"","Saint Just d'Ardeche","","SAINT JUST D'ARDECHE"
"","Neuville sur Vannes","","NEUVILLE SUR VANNES"
"","Escueillens et Saint Just","","ESCUEILLENS ET SAINT JUST","ESCUEILLENS ET ST JUST","91"
"","Luc","","LUC"
"","Pas des Lanciers","","PAS DES LANCIERS","PAS DES LANCIERS","93"
"","Plan de Campagne","","PLAN DE CAMPAGNE","PLAN DE CAMPAGNE","93"
4

4 に答える 4

3

Pythonには次のものがありますtitle()

単語が大文字で始まり、残りの文字が小文字である文字列のタイトルケース バージョンを返します。

このアルゴリズムは、言語に依存しない単純な単語の定義を、連続した文字のグループとして使用します。この定義は多くの文脈で機能しますが、短縮形と所有格のアポストロフィが単語の境界を形成することを意味し、これは望ましい結果ではない可能性があります。

"they're bill's friends from the UK".title() "They'Re Bill'S Friends From The Uk"

アポストロフィの回避策は、正規表現を使用して作成できます。

 import re
 def titlecase(s):
     return re.sub(r"[A-Za-z]+('[A-Za-z]+)?",
                   lambda mo: mo.group(0)[0].upper() +
                              mo.group(0)[1:].lower(),
                   s)

 titlecase("they're bill's friends.") "They're Bill's Friends."

更新: フランス語の問題の解決策は次のとおりです。

import re, sys 

def titlecase(s):
    return re.sub(r"[A-Za-z]+('[A-Za-z]+)?",
        lambda mo: mo.group(0)[0].upper() +
                   mo.group(0)[1:].lower(),
        s)  

def french_parse(s):
    p = re.compile(
        r"( de la | sur | sous | la | de | les | du | le | au | aux | en | des | et )|(( d'| l')([a-z]+))",
        re.IGNORECASE)
    return p.sub(
        lambda mo: mo.group().find("'")>0
                   and mo.group()[:mo.group().find("'")+1].lower() +
                       titlecase(mo.group()[mo.group().find("'")+1:])
                   or (mo.group(0)[0].upper() + mo.group(0)[1:].lower()),
        s); 

for line in sys.stdin:
    s = line[20:len(line)-1]
    p = s.find('"')
    t = s[:p]
    # Just output to show which names have been modified:
    if french_parse( titlecase(t) ) != titlecase(t):
        print '"' + french_parse( titlecase(t) ) + '"'

次のように起動するだけです:

python thepythonscript.py < file.csv

出力は次のようになります。

"Grenand les Sombernon"
"Touville sur Montfort"
"Fontenay en Vexin"
"Durfort Saint Martin de Sossenac"
"Monclar d'Armagnac"
"Ports sur Vienne"
"Saint Barthelemy de Beaurepaire"
"Saint Bernard du Touvet"
"Rosoy le Vieil"
于 2012-09-17T07:21:02.190 に答える
1

vim regex マジックでこれを実現できるかもしれませんが、お気に入りのスクリプト言語で問題を解決し、!コマンドを使用して vim から選択したテキストをパイプする方が簡単だと思います。PHP での (テストされていない) 例を次に示します。

#!/usr/bin/env php
<?php
$specialWords = array('de', 'd\'', 'et', 'du', /* etc. */ );
foreach (file('php://stdin') as $ville) {
    $line = ucwords($line);
    foreach ($specialWords as $w) {
        $line = preg_replace("/\\b$w\\b/i", $w, $line);
    }
    echo $line;
}

そのスクリプトを実行可能にして、あなたのどこかに保存してくださいPATH。次に、vimからテキストを選択し、:'<,'>! yourscript.php変換に使用します(または:%! yourscript.phpバッファ全体のみ)。

于 2012-09-17T07:04:36.460 に答える
0

csv.vim ftpluginは、CSV ファイルでの作業に役立ちます。「列Nの置換」機能を直接提供するわけではありませんが、それに近づくかもしれません。少なくとも、列をきれいなブロックに配置してから、単純な正規表現または視覚的なブロックごとの選択を適用できます。

しかし、Vim でこれを完全に行うよりも、CSV ファイルの操作により適した別のツールチェーンを使用する方が望ましい場合があることに注意してください。また、それが 1 回限りのタスクであるか、頻繁に行うかによっても異なります。

于 2012-09-17T08:04:21.353 に答える
0

これはワンライナーvimコマンドです。

%s/"[^"]*",\zs\("[^"]*"\)/\=substitute(substitute(submatch(0), '\<\(\a\)\(\a*\)\>', '\u\1\L\2', 'g'), '\c\<\(de\|d\|l\|sur\|le\|la\|en\|et\)\>', '\L&', 'g')

ここでは、最初の 2 つのフィールドに二重引用符がないことを期待しています。

このソリューションの背後にある考え方は:h :s\=、見つかった 2 番目のフィールドで一連の関数を実行することに依存することです。一連の関数は次のとおりです。最初に各単語を TitleCase に変更し、次にすべてのライアントを小文字にします。

于 2012-09-17T10:06:30.767 に答える