2016-07-25 5 views
1

長時間/初回。ストリップの正規表現の置き換え

私は職場でのタスク自動化のようなものではなく、主にPython 3.xのために私に役立つ様々な言語でコードする方法を自分自身で教える動きを薬師です。私はautomatethebororingstuff電子ブックを介して作業しており、それが素晴らしい見つける。

第7章の練習問題の1つを完了しようとしています: "文字列を受け取り、strip()文字列メソッドと同じことをする関数を記述してください。文字列を削除すると、空白文字は文字列の先頭と末尾から削除されます。それ以外の場合は、関数の2番目の引数で指定された文字が文字列から削除されます。

文字列に表示したい文字が表示されているときに詰まっています。 'ssstestsss'.strip(S)

#!python3 
import re 

respecchar = ['?', '*', '+', '{', '}', '.', '\\', '^', '$', '[', ']'] 


def regexstrip(string, _strip): 
    if _strip == '' or _strip == ' ': 
     _strip = r'\s' 
    elif _strip in respecchar: 
     _strip = r'\'+_strip' 
    print(_strip) #just for troubleshooting 
    re_strip = re.compile('^'+_strip+'*(.+)'+_strip+'*$') 
    print(re_strip) #just for troubleshooting 
    mstring = re_strip.search(string) 
    print(mstring) #just for troubleshooting 
    stripped = mstring.group(1) 
    print(stripped) 

それが上でそれを実行し、示されたようとして 'testsss 'を得られます(' ssstestsss'、' S')。+それのすべてを取得し、*それをすることができます最後の 'sss'を無視する。もし私が最終的なものを+に変えれば、それは単に「テスト」を生み出すために少ししか改善しない。私がキャプチャグループを貪欲でない(すなわち(+)?)にすると、私はまだ「testsss」を取得し、キャプチャグループの文字クラスから文字を除外して終了文字列アンカーを削除すると(すなわちre.compile('^'+_strip+'*([^'+_strip+'.]+)'+_strip+'*') 「テ」と私は明らかに、その後のエラーを、それを最後列のアンカーを削除しない場合。冗長と散歩-yの質問に対する

謝罪。

私は故意に私のようにすべてのコード(作業中)に含ま私のコードはおそらくむしろ非効率的であることに気付くので、コードを改善することができる他の領域を見ることができれば、教えてください。このコードの実用的なアプリケーションはありませんが、これを学習練習としてやります。

私はこの質問を適切に尋ねて、私の検索で何かを見逃していないことを願っています。

よろしく

Lobsta

+0

エスケープ記号には文字クラスを使用しませんでした。また、 're.escape'を使って特別な文字をエスケープするだけで良いでしょう。 –

+3

'(。+)?'は '(。+?)'と同じではありません。 – Blckknght

答えて

3

あなた(.+)(デフォルト)、貪欲です。同じことをしない、誰かがコメントしたよう(.+?)(.+)?を::ちょうどあなたがthis site

編集でPythonの正規表現をテストすることができ(.+?)
を使用することにより、非貪欲にそれを変更(.+?)(.+)(.+)?ながら、試合の非欲張りバージョンがあります欲張りではない(.+)

+0

ああ私...このようなルーキーエラー。私のルーキーステータスを考えると...それは間違いです。間違っていた遅延修飾子を修正したら、それはうまくいった。 – Lobsta

2

私のコメントで述べたように、あなたはキャラクタークラスに特別な文字を含めませんでした。

また、re.S/re.DOTALL修飾子がない.*は、改行と一致しません。 ^PATTERN|PATTERN$または\APATTERN|PATTERN\Zでの使用を避けることができます(\Aは文字列の先頭に一致し、$は文字列の最後の改行記号の前に一致する可能性があります。$は使用できません) 。

私がいることをPython demo

注を参照してください

import re 

def regexstrip(string, _strip=None): 
    _strip = r"\A[\s{0}]+|[\s{0}]+\Z".format(re.escape(_strip)) if _strip else r"\A\s+|\s+\Z" 
    print(_strip) #just for troubleshooting 
    return re.sub(_strip, '', string) 

print(regexstrip(" ([no more stripping'] ) ", "()[]'")) 
# \A[\s\ \(\)\[\]\']+|[\s\ \(\)\[\]\']+\Z 
# no more stripping 
print(regexstrip(" ([no more stripping'] ) ")) 
# \A\s+|\s+\Z 
# ([no more stripping'] ) 

にあなたのコードを縮小することをお勧めしたい:_strip引数は=None

  • _strip = r"\A[\s{0}]+|[\s{0}]+\Z".format(re.escape(_strip)) if _strip else r"\A\s+|\s+\Z"のINITとオプションである

    • 正規表現パターン:_stripが渡された場合、symb (文字の記号として扱うのが最も簡単な方法です)。
    • re.subで、一致する部分文字列を削除します。
  • +0

    両方の答えを正しいものとしてマークしたいと思います。あなたの答えは同じくらい素晴らしく、私の問題に対する別の(より効率的な)アプローチを示して、私が機能を拡張しようとしている次の部分で私を助けました。また、ATBSがまだ持っていなかったいくつかのPythonのことを教えてくれました。 – Lobsta

    +0

    @Lobsta実際に* a *文字列*をいくつかの文字から取り除きたい場合、文字列に改行があればHolyDannaの答えは機能しません。承認されたステータスを再検討してください。 '。*? 'を使用するという全体の考え方は間違っています。最初から最後まで各シンボルをチェックします。それは膨大なオーバーヘッドです。 –

    関連する問題