2016-08-01 4 views
-1

TL; DR:んPythonでエスケープされた区切り文字で行を分割する

line = "one|two|three\|four\|five" 
fields = line.split(whatever) 

whateverのどのような価値のために:

fields == ['one', 'two', 'three\|four\|five'] 

私はパイプ文字で区切られたファイルを持っています。そのファイルのフィールドの中には、先頭のバックスラッシュでエスケープされたパイプも含まれています。

たとえば、このファイル内のデータの単一の行が['one', 'two', 'three\|four\|five']の配列表現があるかもしれません、これは私は、ファイルを制御することはできませんone|two|three\|four\|five

としてファイルに表されます。私はファイルを前処理することができません。私はを1回の分割で行うことができます。

最終的には、このファイルの各行を別々のフィールドに分割する必要がありますが、先行するバックスラッシュはあらゆる種類の問題であることが判明しています。最初はネガティブ・ルック・アヘッドを使ってみましたが、Pythonの文字列と二重エスケープ文字を取り囲んでいて、理解できないようなものがあります。

解説は説明していますが、任意です。 [^\\]\の異なる任意のcaracterに一致する

[^\\]\| 

+1

エスケープシーケンスを考慮して独自のパーサを記述すると、Pythonのregexがそれを処理できません。 –

+0

最終的に期待される出力は何かを明確にすることができますか? '[one'、two '、' three \ | four \ | five '] 'または' [one '、' two '、' three '、' four '、' five ']'? – Sundeep

+0

@spasic:前者。 –

答えて

0

たぶん、あなたはこのようなものを使用することができます。

あなたが分割を行うために使用されます |続い \以外のものを指定する文字グループを使用します

re.split(r'([^|]+[^\\])\|', line) 

のような正規表現を使用することができます

+0

いいえ、これにはパーサーが必要です。 '' one \\ | two''はどうでしょうか?それはすべきである間に[一致しない](https://regex101.com/r/fM0dF6/1)です。 –

2

余分な空の一致が得られます

リストの冒頭にありますが、うまくいけばそれを回避できます。

re.split(r'([^|]+[^\\])\|', line)[1:] 

もちろん、Wiktorが提起した構文解析の問題

+2

'' one \\ | two''はどうでしょうか?それはすべきである間に[一致しない](https://regex101.com/r/fM0dF6/1)です。エスケープシーケンスがある場合、正規表現は決して正確ではありません。 –

+0

良い点はありますが、何らかの理由で 'split'を使用する必要がある場合は、これが近くにあるかもしれません –

+1

@WiktorStribiżewcのエッジケースが満たされていない場合は気にしません。エスケープ文字をエスケープする必要はありません。 'r '\ |''をデリミタとして認識しないように分割するだけでいいです。あなたの(@EricRenoufの)提案された解決策はうまくいきません。なぜなら素朴な分割は前のフィールドの最後の文字とマッチするから、 '['on'、 'tw'、 'three \\ | four \\ |五 '] '。私は非キャプチャグループとネガティブ先読みの両方でこれを試しましたが、前者はそれをとにかくキャプチャし、後者は何もキャプチャしません。 –

関連する問題