MyEssayのPython正規表現を回す--4つの断言拡張の理解

4731 ワード


 
 
 
 
 
 
 
 
 
 
正規表現では、文字列にサブ列が含まれていることを検出することがよくあります.文字列に単一の文字や文字が含まれていないことを表すのも簡単です.[^...]形式でいいです.ただし、1つの文字列にサブストリングが含まれていないことを示す場合は、[^...]この形式ではだめです.この場合、いわゆる「順方向マッチング」(?=...)という4つの正規表現の拡張マッチングを使用する必要があります.「負の前進マッチング」(?!...)、「順方向後行一致」(?<=...)、「負の後行マッチング」(?のうち...任意の合法的な正規マッチング文字列であってもよい.b単語境界特殊文字と同様に、この4つの断言表現自体もマッチングされた文字列の文字幅を消費することなく、1つのpositionにマッチングするだけである.この4つの断言の理解と記憶については、文の説明を参考にして、2つの面から着手することができる.
  • 前行(lookahead)と後行(lookbehind)とは、実は前を見て後ろを見るという意味です.正規表現エンジンは、文字列と式のマッチングを実行すると、文字列内の文字を最初から最後まで(前から後まで)連続的にスキャンし、スキャンポインタが文字境界を指し、マッチングプロセスに従って移動することを想定します.前行断言は、スキャンポインタがある位置にある場合、エンジンがポインタがスキャンしていない文字に一致しようとするので、ポインタより先にその文字に到達することを前行と呼ぶ.後行は、エンジンがポインタがスキャンした文字に一致しようとすると断言し、ポインタがその文字に到達するので、後行と呼ばれます.記憶方式:後行断言(?<=pattern)、(?
  • いわゆる順方向(positive)と負方向(negative):順方向は一致括弧中の式を表し、負方向は不一致を表す.记忆方式:不等(!=)、论理非(!)全部使ってる!号で表示されているので、あります!番号の形式は不一致、負方向を表す.将!番号を=番号に変更すると、一致、順方向を表します.

  • 特に注意すべき点は,後行方式に対する2つの断言(?<=...)である.と(?、これは後行の断言の使用に一定の困難と面倒をもたらした.以下、これらの断言の使用を具体的な例で説明する(以下の例では一致する文字列とpattern文字列のスペースを明確に表示するために文字⌴で表す):
     
    line 0='⌴def⌴⌴func( funcName,funcParam,funcTime=360)'line 1='⌴def⌴func( funcName,funcParam,funcParam,funcTime=360)'line 2='⌴def⌴func( funcName,funcParam,funcTime=360)'line 2="⌴⌴obj 1(param).func(' func(',func1',',,',,',func',,',',,') line 2="line 2="""'param 1',funcTime=150)#test'line 3="⌴⌴obj 2().funcTest(1)#obj 1(param).func('func 1','param 1')」関数func()の呼び出しを文字列に含めることを望んでいます.すなわち、被試験ラインには「func(」文字列が現れるが、被測定ラインには関数funcに対する定義が含まれていない.すなわち、「def func(」文字列が現れず、defとfuncの間に複数のスペースが含まれる可能性がある.最も直接的な考え方では、「func(」文字列に一致し、「func(」の前に「defs+」が現れないパターンの文字列であるため、まず、line 1、すなわちreに負の後行マッチング方式を適用することを考慮する.findall(r"(?(defの後ろにスペースがあります)では、一致するコンテンツは得られないと予想され、間もなく結果は[]空のリストになりますが、実際に得られたのは:
    >>> re.findall(r"(? ['⌴⌴⌴func(']
    「func」の前には3つのスペースがあります.これはなぜですか.なぜなら、reエンジンは「s*func(」モードの文字列を見つけようとし、この文字列の前に「def
    では、負の後行マッチング断言のdefの後ろのスペースを削除する、すなわちreに変更しようとする.findall("(?
    >>> re.findall(r"(? ['⌴⌴func(']
    「func」の前に2つのスペースがあります.よく分析すると、reエンジンが「s*func(」モードの文字列を見つけようとし、この文字列の前に「def」文字列(defの後にスペースがない)が現れないためです.2つの前置スペースを含む「⌴⌴func(」は、2つのスペースを含む「⌴⌴func(」文字列が「s*func(」のパターンに一致し、この文字列の前には負の後行にpattern「(?
    負の後行マッチング断言でdefの後にs+を使用する、すなわちreに変更してみよう.findall(「(?後行方式の2つの断言は式文字列の内容を一定長に一致させる必要があるため、このような実行結果はPython解釈器がエラーを報告する」error:look-behind requires fixed-width pattern」
    -したがって、defとfuncの間に3つのスペースを含むline 1に対して、負の後行断言でマッチングを実現するには、defの後に3つのスペースを含むfuncの前にスペースがないreを使用する必要がある.findall(「だから負の後行断言方式ではdefとfuncの間のスペース数が未知の文字列に正確に一致しない.
    そこで、正確なマッチング、すなわちreを実現するために、負の前進断言を採用することしか考えられない.findall("^(?!*defs+func().*func(",line 1)は、実行結果が空のリスト[]であるとともに、順方向断言を使用して一致する文字列が正しく使用されていることを検証し、reを実行する.findall("^(?=.*defs+func().*func(",line 1)で得られた結果は['def func(']
    >>> re.findall("^(?!.*def\s+func\().*func\(", line1) [] >>> re.findall("^(?=.*def\s+func\().*func\(", line1) ['⌴def⌴⌴⌴func(']
    --これは私たちの負の前進断言がdefとfuncの間に不定長のスペース数がある場合に正確に一致していることを示しています.ここでは、ここでの負の前進断言の意味を説明します:「^(?!*defs+func().*func(」は、lineの開始位置から後方への検索を表し、「.*defs+func(」というパターンの文字列は許されませんが、これを前提に「.*func(」パターンに一致する文字列を探してみましょう.これは、私たちが望んでいるフィルタ条件です.ここの(?!*defs+func()文字列の長さを消費しません
    ここで特に注意すべきは、他の2つとreである.findall("^(?!*defs+func().*func(",line 1)に近いマッチングモード:
    1、reを使用する場合.findall("^(?!defs+func().*func(",line 1)では、実行結果が予想される空のリストではなく、これは、REエンジンが開始位置が「defs+func(」ではなく「.*func(」の文字列であるかどうかを検索しようとするためであるが、line 1の「def」の前にちょうどスペースがあるため、REエンジンが開始位置から検索したのは、負の前方式にスペースがない「defs+func(」モードの文字列ではなく、前置スペースのある「パターン文字列なので、一致します.
    2、reを使用する場合.findall(「(?!*defs+func().*func(」,line 1)は、実行結果も予想される空のリストではなく、「'ef⌴⌴func(')です.これはpatternに^文字がない場合、line 1が最初からマッチング条件を満たさなければならないのではなく、line 1の任意の位置がマッチング条件を満たすことができるので、line 1の「ef⌴⌴func(」という文字列はマッチング条件を満たすことができます.以上、正規マッチングを試してみることをお勧めします「xxxの前にyyyが現れず、xxxとyyyyの間に他の不定長文字列が存在する可能性がある」というシーンでは、負の前進断言を優先的に考慮する.xxxとyyyyの間が一定長であると判断できる場合は、負の後行断言を用いることができる
    さらに、例えば、line 3において「func(」文字列が一致する場合、「func(」の前に#記号が現れないこと、すなわちfunc関数を要求する呼び出し文が注釈されていないことを考慮すると、#とfunc(間の文字長は完全にランダムで未知であるため、re.findall("^(?.*#.*func().*func().*func(",line 3)は、re.findall("(?
     
     
     
     
     
     
    import re
    
    
    id='Slot   1/Port   3'
    
    # ppatten= re.compile(r'(?!.+Port\s+)\d+\.?\d*')
    ppatten= re.compile(r'(?!Slot\s+)\d+\.?\d*')
    print(re.findall(ppatten,id))
    line1 = ' def   func(funcName, funcParam, funcTime=360) '
    print(re.findall("^(?=.*def\s+func\().*func\(", line1))