2016-03-02 73 views
1

我使用正则表达式如下解析我的应用程序日志文件中搜索特定字符串做一个字符串确定特定字符的存在

\[\s*\b(?:[0-9A-Za-z][0-9A-Za-z-_.#]{0,200})(?:\.(?:[0-9*A-Za-z][0-9A-Za-z-_.#]{0,200}))*(\.?|\b)\s*] 

这工作得很好,但现在我们需要确保字符串“必须”包含匹配的“ - ”字符。我很困惑把这个条件添加到最初的regx。 任何指针都会有帮助。

感谢和问候, Santhosh

+0

是'-'应该是在特定的位置? – Trasiva

+0

@Trasiva,我们只需要确保存在。它不是位置特定的 – kallada

+0

我总是建立我的正则表达式查询测试他们与这个伟大的工具:http://regexr.com/您可以看到,如果您的查询是在实时工作,同时进行更改,使正则表达式a很容易:) – Kocik

回答

2

正则表达式方括号,[]内部的串相匹配,并且可以仅由非[和非]符号。

您可以像支票开[后轻松地添加了积极前瞻的限制,如果超过][等下一个字符,随后用-

\[           # opening [ 
    (?=[^\]\[]*-)        # There must be a hyphen in [...] 
    \s*           # 0+ whitespaces 
    \b(?:[0-9A-Za-z][0-9A-Za-z-_.#]{0,200})  # Part 1 (with obligatory subpattern) 
    (?:\.          # Part 2, optional 
     (?:[0-9*A-Za-z][0-9A-Za-z-_.#]{0,200}) 
)* 
    (\.?|\b)         # optional . or word boundary 
\s*           # 0+ whitespaces 
]            # closing ] 

regex demo

而且一one-liner

\[(?=[^\]\[]*-)\s*\b(?:[0-9A-Za-z][0-9A-Za-z-_.#]{0,200})(?:\.(?:[0-9*A-Za-z][0-9A-Za-z-_.#]{0,200}))*(\.?|\b)\s*] 

提示:使用详细的/x修饰符将模式分割为单独的多行块进行分析,它将在将来需要再次修改模式时帮助您。

如果只有在-@存在于[...]内时才需要匹配,请将lookahead修改为(?=[^\]\[]*[[email protected]])。对于更一般的情况,请在预览内的其他组内使用(?=[^\]\[]*(?:one|another|must-be-present))替代方案。

+0

这是一个好主意,可以检查代码中的“黑客”,并且可以通过代码本身添加其他(以及当前)限制。 –

+0

非常感谢。现在我遇到了一个需要检查 - 或@的情况,以取得圆满成功。所以我试图修改(?= [^ \] \ [] * - )#这行中必须有一个连字符(?= [^ \] \ [] * - | @)#There必须是连字符或@中的[...]。但是这个表情还没有考虑用@来刺激。 – kallada

+0

如果必须有'-'或'@',请将'lookahead'修改为'(?= [^ \] \ [] * [ - @])''。 –

0

这个条件会工作,如果只是想确保 - 运行你的代码块之前,你的字符串中出现。

if (myString.indexOf('-') >= 0) { 
    //your code 
} 
+0

我们可以只用正则表达式吗? – kallada

+0

是的,我们可以:)。 –

0

如果你必须有一个连字符,你就必须要么重复大部分的图案,或检查它在第二阶段:

if re.match(pattern, line): 
    if not '-' in line: 
     raise MissingDash('No dash in line: {}'.format(line)) 

我建议将第二请检查,因为向正则表达式添加要求会使其阅读更加糟糕。

+0

为什么选择Python?正则表达式读起来并不可怕,这对我来说很清楚。 –

+0

他们使用* some *语言的正则表达式,Python在这个级别上很容易阅读和理解。至于'为什么要用代码',好吧,OP似乎可能更容易处理。 –

+0

我同意,但要求是一个要求。当不添加语言标签时,给出特定语言的答案就像是在黑暗中拍摄的照片。真的,这个正则表达式并不可怕。当一个模式充满了反向引用,lookaround和子程序调用(或平衡结构)时,情况会更糟糕。这是一个典型的线性模式,只包含字符类,组,量词,文字符号。比它可能长一点,但是当分裂时,它是可读的。 –

1

更新答案 - 断言

在这种情况下,更好的方式来做到这一点是使用断言包括检查只预计有问题的字符相匹配的位置的的。

我知道这很简单,但使用outter伪锚文本\[ ... \]
不能在体内存在的分隔符是一个罕见的。

你应该总是尽量避免这样做。
事情变了,你的意见可能会改变。
规则已知字符是验证遵循中间串只是其中
使用断言验证时使用。

这避免了依赖的必要性是什么根本不存在的那一刻即不是]
而应该依靠什么那里。

同样,这属于中间字符串的匹配。
BOL/EOL是完全不同的东西^$,并且是一个更持久的构造
利用它。

智能代码总是更好。

\[\s*\b(?=[0-9A-Za-z][0-9A-Za-z_.#]{0,199}-|[0-9A-Za-z][0-9A-Za-z_.#]{0,200}(?:\.[0-9*A-Za-z][0-9A-Za-z_.#]{0,200})*\.[0-9*A-Za-z][0-9A-Za-z_.#]{0,199}-)(?:[0-9A-Za-z][0-9A-Za-z_.#-]{0,200})(?:\.(?:[0-9*A-Za-z][0-9A-Za-z_.#-]{0,200}))*(\.?|\b)\s*\] 

使用条件语句

如果你的引擎支持条件语句,最简单的方式是不依赖于伪锚文本,即侥幸
[..]

\[\s*\b[0-9A-Za-z](?:[0-9A-Za-z_.#]|(-)){0,200}(?:\.(?:[0-9*A-Za-z](?:[0-9A-Za-z_.#]|(-)){0,200}))*(\.?|\b)\s*\](?(1)|(?(2)|(?!)))

扩展

\[ \s* \b 
[0-9A-Za-z] 
(?: 
     [0-9A-Za-z_.#] 
    | (-)       # (1) 
){0,200} 
(?: 
     \. 
     (?: 
      [0-9*A-Za-z] 
      (?: 
       [0-9A-Za-z_.#] 
      | (-)       # (2) 
      ){0,200} 
    ) 
)* 
(\.? | \b)     # (3) 
\s* \] 

(?(1)       # Fail if no dash found 
    | (?(2) 
     | (?!) 
    ) 
) 
+0

不幸的是我不支持条件 – kallada

相关问题