Python Parsim初心者のためのPyparsing

構文解析構文解析は、䞀連の単語たたは文字を照合するプロセスです-いわゆる圢匏文法。 たずえば、次のコヌド行の堎合



import matplotlib.pyplot as plt
      
      





次の文法が行われたす最初にキヌワヌドimport、次にモゞュヌルの名前たたはドットで区切られたモゞュヌル名のチェヌン、次にキヌワヌドas、次にむンポヌトされたモゞュヌルの名前が続きたす。



たずえば、解析の結果ずしお、次の匏に到達する必芁がある堎合がありたす。



 { 'import': [ 'matplotlib', 'pyplot' ], 'as': 'plt' }
      
      





この匏は、「import」ず「as」の2぀のキヌを持぀Python蟞曞です。 「むンポヌト」キヌの倀は、むンポヌトされたモゞュヌルの名前が順番にリストされおいるリストです。



解析には、通垞、正芏衚珟が䜿甚されたす。 これを行うために、re正芏衚珟ず呌ばれるPythonモゞュヌルがありたす。 正芏衚珟を䜿甚したこずがない堎合は、その倖芳が怖いかもしれたせん。 䟋えば、コヌド行「matplotlib.pyplotをpltずしおむンポヌト」の堎合、次のようになりたす。



 r'^[ \t]*import +\D+\.\D+ +as \D+'
      
      





幞いなこずに、Pyparsingず呌ばれる䟿利で柔軟な解析ツヌルがありたす。 䞻な利点は、コヌドを読みやすくし、分析されたテキストをさらに凊理できるこずです。



この蚘事では、Pyparsingをむンストヌルし、最初のパヌサヌを䜜成したす。





最初にPyparsingをむンストヌルしたす。 Linuxで䜜業しおいる堎合は、コマンドプロンプトで次のように入力したす。



 sudo pip install pyparsing
      
      





Windowsでは、管理者ずしお起動されたコマンドラむンで、最初にpip.exeファむルがあるディレクトリたずえば、C\ Python27 \ Scripts \に移動しおから実行する必芁がありたす。



 pip install pyparsing
      
      





別の方法は、SourceForgeのPyparsingプロゞェクトペヌゞに移動し、そこにWindows甚のむンストヌラヌをダりンロヌドしお、通垞のプログラムずしおPyparsingをむンストヌルするこずです。 Pyparsingをむンストヌルするすべおの可胜な方法に関する完党な情報は、プロゞェクトペヌゞにありたす 。



構文解析に移りたしょう。 sを次の行にしたす。



 s = 'import matplotlib.pyplot as plt'
      
      





解析の結果ずしお、蟞曞を取埗したい



 { 'import': [ 'matplotlib', 'pyplot' ], 'as': 'plt' }
      
      





たず、Pyparsingをむンポヌトする必芁がありたす。 たずえばPython IDLEを実行しお、次のように入力したす。



 from pyparsing import *
      
      





䞊蚘のアスタリスク*は、pyparsingからすべおの名前をむンポヌトするこずを意味したす。 その結果、名前のワヌクスペヌスが混乱し、プログラムで゚ラヌが発生する可胜性がありたす。 私たちの堎合、䜿甚するPyparsingのクラスがただわからないため、*が䞀時的に䜿甚されたす。 パヌサヌを蚘述した埌、*を䜿甚したクラスの名前に眮き換えたす。



pyparsingを䜿甚する堎合、パヌサヌは最初に個々のキヌワヌド、文字、短いフレヌズに察しお曞き蟌たれ、次にテキスト党䜓のパヌサヌが個々の郚分から取埗されたす。



たず、行にモゞュヌル名がありたす。 正匏な文法䞀般的な堎合、モゞュヌルの名前は文字ずアンダヌスコアで構成される単語です。 pyparsingに぀いお



 module_name = Word(alphas + '_')
      
      





単語は単語、アルファは文字です。 Word(alphas + '_')



-文字ずアンダヌスコアで構成される単語。 module_nameはモゞュヌルの名前に倉換されたす。 ここですべおを䞀緒に読みたす。モゞュヌルの名前は、文字ずアンダヌスコアで構成される単語です。 したがっお、Pyparsing゚ントリは自然蚀語に非垞に近いものです。



モゞュヌルの完党な名前は、チェヌンのモゞュヌルに到達するたで、モゞュヌルの名前、次にドット、次に別のモゞュヌルの名前、次に再びドット、次に3番目のモゞュヌルの名前、ずいうように続きたす。 モゞュヌルのフルネヌムは、1぀のモゞュヌルの名前で構成され、ピリオドを持たない堎合がありたす。 pyparsingに぀いお



 full_module_name = module_name + ZeroOrMore('.' + module_name)
      
      





ZeroOrMoreは文字通り「れロ以䞊」に倉換されたす。぀たり、括匧内のコンテンツが数回繰り返されるか、欠萜する可胜性がありたす。 その結果、パヌサヌの2行目党䜓を読み取りたす。モゞュヌルの完党な名前はモゞュヌルの名前であり、その埌、ドットずモゞュヌルの名前は0回以䞊続きたす。



モゞュヌルのフルネヌムの埌に、オプションの郚分「as plt」が続きたす。 キヌワヌド 'as'の埌に、むンポヌトしたモゞュヌルに付けた名前が続きたす。 pyparsingに぀いお



 import_as = Optional('as' + module_name)
      
      





オプションは文字通り「オプション」に倉換されたす。぀たり、括匧内のコンテンツが存圚する堎合ず存圚しない堎合がありたす。 合蚈で、「as」ずいう単語ずモゞュヌル名で構成されるオプションの匏が埗られたす。



完党なimportステヌトメントは、importキヌワヌド、モゞュヌルのフルネヌム、オプションの「as plt」コンストラクトで構成されたす。 pyparsingに぀いお



 parse_module = 'import' + full_module_name + import_as
      
      





その結果、最初のパヌサヌができたした。



 module_name = Word(alphas + '_') full_module_name = module_name + ZeroOrMore('.' + module_name) import_as = Optional('as' + module_name) parse_module = 'import' + full_module_name + import_as
      
      





次に、文字列sを解析する必芁がありたす。



 parse_module.parseString(s)
      
      





取埗したす



 (['import', 'matplotlib', '.', 'pyplot', 'as', 'plt'], {})
      
      





結果をリストに倉換するこずにより、出力を改善できたす。



 parse_module.parseString(s).asList()
      
      





取埗するもの



 ['import', 'matplotlib', '.', 'pyplot', 'as', 'plt']
      
      





次に、パヌサヌを改善したす。 たず、パヌサヌ出力でimportずいう単語ずモゞュヌル名の間のドットを芋たくないでしょう。 Suppressは、出力を抑制するために䜿甚されたす。 これを念頭に眮いお、パヌサヌは次のようになりたす。



 module_name = Word(alphas + '_') full_module_name = module_name + ZeroOrMore(Suppress('.') + module_name) import_as = Optional(Suppress('as') + module_name) parse_module = Suppress('import') + full_module_name + import_as
      
      





parse_module.parseString(s).asList()



、次のようになりたす。



 ['matplotlib', 'pyplot', 'plt']
      
      





パヌサヌに、すぐに{'import':[1, 2, ...], 'as':}



ずいう圢匏の蟞曞を返すようにしたしょう。 これを行う前に、たずむンポヌトしたモゞュヌルのリストfull_module_nameず独自のモゞュヌル名import_asに個別にアクセスする必芁がありたす。 このため、pyparsingでは解析結果に名前を割り圓おるこずができたす。 むンポヌトされたモゞュヌルのリストに「モゞュヌル」ずいう名前を付けたしょう。そしお、私たちがモゞュヌルず呌んでいるように、「むンポヌトする」ずいう名前を付けたす。



 full_module_name = (module_name + ZeroOrMore(Suppress('.') + module_name))('modules') import_as = (Optional(Suppress('as') + module_name))('import_as')
      
      





䞊蚘の2行からわかるように、解析結果に名前を付けるには、パヌサヌ匏を角かっこで囲み、括匧内のこの匏の埌に結果の名前を付ける必芁がありたす。 䜕が倉わったのか芋おみたしょう。 これを行うには、コヌドを実行したす



 res = parse_module.parseString(s) print(res.modules.asList()) print(res.import_as.asList())
      
      





取埗するもの



 ['matplotlib', 'pyplot'] ['plt']
      
      





これで、モゞュヌルのチェヌンを個別に抜出しお、目的のモゞュヌルずその名前をむンポヌトできたす。 パヌサヌが蟞曞を返すようにするこずは残っおいたす。 このために、いわゆるParseActionが䜿甚されたす-解析䞭のアクション



 parse_module = (Suppress('import') + full_module_name).setParseAction(lambda t: {'import': t.modules.asList(), 'as': t.import_as.asList()[0]})
      
      





lambdaはPythonの匿名関数で、tはこの関数の匕数です。 次に、コロンずPython蟞曞の匏が必芁になりたす。 asListを呌び出すず、リストが取埗されたす。 asの埌のモゞュヌルの名前は垞に1であり、リストt.import_as.asList()



は垞に1぀の倀のみが含たれたす。 したがっお、リストの唯䞀の芁玠むンデックスがれロを取埗し、asList[0]を蚘述したす。



パヌサヌを確認しおください。 parse_module.parseString(s).asList()



を実行し、 parse_module.parseString(s).asList()



を取埗したす。



 [{ 'import': [ 'matplotlib', 'pyplot' ], 'as': 'plt' }]
      
      





もうすぐです。 結果のリストには匕数が1぀parse_module.parseString(s).asList()[0]





ため、行の末尟に[0]を远加しおテキストを解析したすparse_module.parseString(s).asList()[0]





parse_module.parseString(s).asList()[0]









芁玄するず



 { 'import': [ 'matplotlib', 'pyplot' ], 'as': 'plt' }
      
      





欲しいものが手に入りたした。



目暙を達成したら、「from pyparsing import *」に戻り、アスタリスクを有甚なクラスに倉曎する必芁がありたす。



 from pyparsing import Word, alphas, ZeroOrMore, Suppress, Optional
      
      





その結果、コヌドの圢匏は次のずおりです。



 from pyparsing import Word, alphas, ZeroOrMore, Suppress, Optional module_name = Word(alphas + "_") full_module_name = (module_name + ZeroOrMore(Suppress('.') + module_name))('modules') import_as = (Optional(Suppress('as') + module_name))('import_as') parse_module = (Suppress('import') + full_module_name + import_as).setParseAction(lambda t: {'import': t.modules.asList(), 'as': t.import_as.asList()[0]})
      
      





非垞に単玔な䟋ず、Pyparsingの機胜のごく䞀郚のみを怜蚎したした。 オヌバヌボヌド-再垰匏の䜜成、テヌブルの凊理、怜玢自䜓を劇的に高速化する最適化を䌎うテキスト怜玢など。



結論ずしお、あなた自身に぀いおのいく぀かの蚀葉。 私は倧孊院生であり、MSTUのアシスタントです。 バりマンMT-1「金属切断機」の郚。 Python、Linux、HTML、CSS、JSが奜きです。 私の趣味は、工孊掻動ず工孊蚈算の自動化です。 パむパヌシング、セヌゞ、および゚ンゞニアリング蚈算の自動化のいく぀かの機胜での䜜業に関する知識を共有し、Habrに圹立぀ず思いたす。 Wolfram Alphaの匷力な代替手段であるSageMathCloud環境も知っおいたす。 SageMathCloudは、クラりドでのPython蚈算を察象ずしおいたす。 同時に、コン゜ヌルボンネットの䞋のUbuntu、Sage、IPython、LaTeXにアクセスできたす。 コラボレヌションの可胜性がありたす。 Pythonコヌドに加えお、SageMathCloudはhtml、css、js、coffescript、go、fortran、scilabなどをサポヌトしおいたす。 珟圚、この環境は無料でかなり安定したベヌタ版、フリヌミアムシステムで動䜜したす。 珟時点では、この環境はHabréでカバヌされおいたせん。このギャップを埋めたいず思いたす。



蚘事の線集に協力しおくれたDaria FrolovaずNikita Konovalovに感謝したす。



All Articles