7

我正在做一些正则表达式体操。我为自己设定了尝试搜索 C# 代码的任务,其中使用了 as-operator 而不是在合理的空间内进行空检查。现在我不想解析 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)

因此,任何随机空检查都将算作“良好检查”,因此不会被发现。

问题是:我如何匹配某些东西,同时确保在其周围环境中找不到其他东西。

我尝试过天真的方法,寻找“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

.{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 回答
2

问题不清楚。你到底想要什么?我很遗憾,但在阅读了无数次问题和评论后,我仍然不明白。

.

代码必须在 C# 中吗?在 Python 中?其他 ?没有关于这一点的迹象

.

仅当if(... == ...)一行跟随一行行时才需要匹配var ... = ...吗?

或者异质线可能在块和if(... == ...) 线之间而不停止匹配?

我的代码将第二个选项设为 true。

.

if(... == null) 一行之后的一行是否if(... == ...)停止匹配?

无法理解是或否,我定义了两个正则表达式来捕捉这两个选项。

.

我希望我的代码足够清晰并回答您的关注。

它在 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. 寻找一个“as”赋值——你可能需要一个更好的正则表达式来寻找实际的赋值,并且可能想要存储赋值的表达式,但现在让我们使用“\bas\b”
  2. 如果您看到if (... == null)150 个字符以内的字符,请不要匹配
  3. 如果您没有看到if (... == null)150 个字符以内的字符,请匹配

由于负面的前瞻性,您的表达\bas\b.{1,150}(?!\b==\s*null\b)将不起作用。正则表达式总是可以向前或向后跳过一个字母,以避免这种负面的前瞻,即使有一个字母,你最终也会匹配if (... == null)

正则表达式真的不擅长匹配的东西。在这种情况下,您最好尝试将“as”分配与 150 个字符内的“if == null”检查匹配:

\bas\b.{1,150}\b==\s*null\b

然后否定检查:if (!regex.match(text)) ...

于 2011-03-22T07:03:23.000 回答
1
(?s:\s+as\s+(?!.{0,150}==\s*null\b))

我正在使用 激活 SingleLine 选项?s:。如果需要,您可以将其放入 Regex 的选项中。我要补充一点,因为我认为只有空格\s在. 你可能可以把喜欢asas\b

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

请注意,这\s可能会捕获不是“有效空间”的空间。它被定义为“分隔符,空格”类别[\f\n\r\t\v\x85\p{Z}]\p{Z}的Unicode 字符加上“分隔符,行”类别中的 Unicode 字符加上“分隔符,段落”类别中的 Unicode 字符

于 2011-03-23T12:39:28.507 回答