7

私は正規表現の体操をしています。私は、適切なスペース内でヌル チェックが続かない as-operator の使用がある C# コードを検索しようとするタスクを自分自身に設定しました。今は C# コードを解析したくありません。たとえば、次のようなコード スニペットをキャプチャしたい

    var x1 = x as SimpleRes;
    var y1 = y as SimpleRes;
    if(x1.a == y1.a)

ただし、キャプチャしない

    var x1 = x as SimpleRes;
    var y1 = y as SimpleRes;
    if(x1 == null)

それどころか

    var x1 = x as SimpleRes;
    var y1 = y as SimpleRes;
    if(somethingunrelated == null) {...}
    if(x1.a == y1.a)

したがって、任意のランダムな null チェックは「適切なチェック」としてカウントされるため、検出されません。

問題は、周囲に何か他のものが見つからないようにしながら、どうすれば何かを一致させることができるかということです。

私は単純なアプローチを試み、「as」を探してから、150 文字以内で否定的な先読みを行いました。

\bas\b.{1,150}(?!\b==\s*null\b)

上記の正規表現は、残念ながら上記の例のすべてに一致します。問題は、先読みしてから否定的な先読みを行うと、先読みで「== null」が見つからない多くの状況が見つかる可能性があることです。

式全体を否定しようとしても、それは役に立ちません。それは、ほとんどの C# コードと一致します。

4

6 に答える 6

11

私は正規表現の体操が大好きです!コメント付きの PHP 正規表現を次に示します。

$re = '/# Find all AS, (but not preceding a XX == null).
    \bas\b               # Match "as"
    (?=                  # But only if...
      (?:                # there exist from 1-150
        [\S\s]           # chars, each of which
        (?!==\s*null)    # are NOT preceding "=NULL"
      ){1,150}?          # (and do this lazily)
      (?:                # We are done when either
        (?=              # we have reached
          ==\s*(?!null)  # a non NULL conditional
        )                #
      | $                # or the end of string.
      )
    )/ix'

そして、これはJavascriptスタイルです:

re = /\bas\b(?=(?:[\S\s](?!==\s*null)){1,150}?(?:(?===\s*(?!null))|$))/ig;

これはちょっと頭が痛くなりました…。

私が使用しているテストデータは次のとおりです。

text = r"""    var x1 = x as SimpleRes;
    var y1 = y as SimpleRes;
    if(x1.a == y1.a)

however, not capture
    var x1 = x as SimpleRes;
    var y1 = y as SimpleRes;
    if(x1 == null)

nor for that matter
    var x1 = x as SimpleRes;
    var y1 = y as SimpleRes;
    if(somethingunrelated == null) {...}
    if(x1.a == y1.a)"""
于 2011-03-16T22:44:42.950 に答える
2

質問は明確ではありません。あなたは正確に何をしたいですか?申し訳ありませんが、質問とコメントを何度も読んだ後でも、まだ理解できません。

.

コードは C# でなければなりませんか? パイソンで?他の ?この点に関する指摘はない

.

if(... == ...)行が行のブロックに続く場合にのみ一致が必要ですvar ... = ...か?

if(... == ...) または、マッチングを停止せずに、異種の行がブロックと行の間にある可能性がありますか?

私のコードでは、2 番目のオプションを true としています。

.

if(... == null) 行の後の行if(... == ...)はマッチインを停止しますか?

はいかいいえかを理解できないため、これら 2 つのオプションをキャッチするために 2 つの正規表現を定義しました。

.

私のコードが十分に明確で、あなたの関心事に答えてくれることを願っています。

それはPythonにあります

import re

ch1 ='''kutgdfxfovuyfuuff
var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
if(x1.a == y1.a)
1618987987849891
'''

ch2 ='''kutgdfxfovuyfuuff
var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
uydtdrdutdutrr
if(x1.a == y1.a)
3213546878'''

ch3='''kutgdfxfovuyfuuff
var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
if(x1 == null)
165478964654456454'''

ch4='''kutgdfxfovuyfuuff
var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
hgyrtdduihudgug
if(x1 == null)
165489746+54646544'''

ch5='''kutgdfxfovuyfuuff
var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
if(somethingunrelated == null ) {...}
if(x1.a == y1.a)
1354687897'''

ch6='''kutgdfxfovuyfuuff
var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
ifughobviudyhogiuvyhoiuhoiv
if(somethingunrelated == null ) {...}
if(x1.a == y1.a)
2468748874897498749874897'''

ch7 = '''kutgdfxfovuyfuuff
var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
if(x1.a == y1.a)
iufxresguygo
liygcygfuihoiuguyg
if(somethingunrelated == null ) {...}
oufxsyrtuy
'''

ch8 = '''kutgdfxfovuyfuuff
var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
tfsezfuytfyfy
if(x1.a == y1.a)
iufxresguygo
liygcygfuihoiuguyg
if(somethingunrelated == null ) {...}
oufxsyrtuy
'''

ch9 = '''kutgdfxfovuyfuuff
var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
tfsezfuytfyfy
if(x1.a == y1.a)
if(somethingunrelated == null ) {...}
oufxsyrtuy
'''

pat1 = re.compile(('('
                   '(^var +\S+ *= *\S+ +as .+[\r\n]+)+?'
                   '([\s\S](?!==\s*null\\b))*?'
                   '^if *\( *[^\s=]+ *==(?!\s*null).+$'
                   ')'
                   ),
                  re.MULTILINE)

pat2 = re.compile(('('
                   '(^var +\S+ *= *\S+ +as .+[\r\n]+)+?'
                   '([\s\S](?!==\s*null\\b))*?'
                   '^if *\( *[^\s=]+ *==(?!\s*null).+$'
                   ')'
                   '(?![\s\S]{0,150}==)'
                   ),
                  re.MULTILINE)


for ch in (ch1,ch2,ch3,ch4,ch5,ch6,ch7,ch8,ch9):
    print pat1.search(ch).group() if pat1.search(ch) else pat1.search(ch)
    print
    print pat2.search(ch).group() if pat2.search(ch) else pat2.search(ch)
    print '-----------------------------------------'

結果

>>> 
var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
if(x1.a == y1.a)

var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
if(x1.a == y1.a)
-----------------------------------------
var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
uydtdrdutdutrr
if(x1.a == y1.a)

var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
uydtdrdutdutrr
if(x1.a == y1.a)
-----------------------------------------
None

None
-----------------------------------------
None

None
-----------------------------------------
None

None
-----------------------------------------
None

None
-----------------------------------------
var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
if(x1.a == y1.a)

None
-----------------------------------------
var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
tfsezfuytfyfy
if(x1.a == y1.a)

None
-----------------------------------------
var x1 = x as SimpleRes;
var y1 = y as SimpleRes;
tfsezfuytfyfy
if(x1.a == y1.a)

None
-----------------------------------------
>>> 
于 2011-03-17T13:52:52.193 に答える
2

.{1,150}先読みの中に を置き、(一般に、改行には一致.しません) に置き換えます。また、 は の近くで誤解を招く可能性があります。\s\S.\b==

\bas\b(?![\s\S]{1,150}==\s*null\b)
于 2011-02-07T12:49:41.630 に答える
2

変数名を () に入れると、後方参照として使用できるようになると思います。次のようなもの、

\b(\w+)\b\W*=\W*\w*\W*\bas\b[\s\S]{1,150}(?!\b\1\b\W*==\W*\bnull\b)
于 2011-03-17T01:33:12.350 に答える
1
(?s:\s+as\s+(?!.{0,150}==\s*null\b))

で SingleLine オプションを有効にしています?s:。必要に応じて、正規表現のオプションに入れることができます。.の周りにスペースだけが「合法」であると思うので、私が置い\sていることを付け加えておきます。あなたはおそらく好きなものを置くことができますasas\b

(?s:\b+as\b(?!.{0,150}==\s*null\b))

\sおそらく「有効なスペース」ではないスペースをキャッチすることに注意してください。これは、「セパレータ、スペース」カテゴリの Unicode 文字と、「セパレータ、行」カテゴリの Unicode 文字、および「セパレータ、段落」カテゴリの Unicode 文字である定義[\f\n\r\t\v\x85\p{Z}]\p{Z}ています。

于 2011-03-23T12:39:28.507 に答える