在正则表达式中找不到单词

时间:2011-04-09 21:38:04

标签: regex expression words

我已经看到在正则表达式中发现缺少字符的示例,我试图找到正则表达式中缺少单词(可能使用负面的lookbehind)。

我有这样的代码行:

示例一:

protected static readonly string BACKGROUND_MUSIC_NAME = "Music_Mission_Complete_Loop_audio";

这是另一个:

mainWindow.Id = "MainWindow";

最后一个:

mainStoLabel.Text = "#stb_entry_clah";

我想通过找到像这样的所有字符串来捕获中间字符a。)在引号之间的实际字符串中没有前面的“#”,并且b。)之前根本没有单词“readonly”。

我当前的正则表达式是:

.*\W\=\W"[^#].*"

它捕获了前两个例子。现在我只想缩小最上面的例子。如何捕获整个单词的缺失(不是字符)。

感谢。

4 个答案:

答案 0 :(得分:2)

我完全不明白你的问题,否定的前瞻看起来像这样:

(?!.*readonly)(?:.*\s\=\s"[^#].*")

如果字符串中没有“readonly”一词,第一部分将匹配。

您使用的是哪种语言?

你想要匹配什么,只有第二个例子,我理解这是正确的吗?

答案 1 :(得分:2)

你的否定先行断言中的错误是你没有把它整合在一起以适应一般情况。当你向前爬行时,你需要使它的断言适用于每个角色位置。它只适用于你编写它的一个可能的点,而你需要它适用于所有这些点。请参阅下文,了解如何正确执行此操作。

这是一个工作演示,展示了两种不同的方法:

  1. 第一个使用负向前瞻以确保左侧部分不包含只读且右侧部分不以数字符号开头。

  2. 第二个做一个更简单的解析器,然后分别检查左侧和右侧是否适用于每个约束。

  3. 演示语言是Perl,但是相同的模式和逻辑几乎无处不在。

    #!/usr/bin/perl
    
    while (<DATA>) {
        chomp;
    #
    # First demo: use a complicated regex to get desired part only
    #
        my($label) = m{
            ^                           # start at the beginning
            (?:                         # noncapture group:
                (?! \b readonly \b )    #   no "readonly" here
                .                       #   now advance one character
            ) +                         # repeated 1 or more times
            \s* = \s*                   # skip an equals sign w/optional spaces
            " ( [^#"] [^"]* ) "         # capture #1: quote-delimited text
                                        #   BUT whose first char isn't a "#"
        }x;
    
        if (defined $label) {
            print "Demo One: found label <$label> at line $.\n";
        }
    #
    # Second demo: This time use simpler patterns, several
    #
        my($lhs, $rhs) = m{
            ^                       # from the start of line
            ( [^=]+ )               # capture #1: 1 or more non-equals chars
            \s* = \s*               # skip an equals sign w/optional spaces
            " ( [^"]+ ) "           # capture #2: all quote-delimited text
        }x;
    
        unless ($lhs =~ /\b readonly \b/x || $rhs =~ /^#/) {
            print "Demo Two: found label <$rhs> at line $.\n";
        }
    
    }
    __END__
    protected static readonly string BACKGROUND_MUSIC_NAME = "Music_Mission_Complete_Loop_audio";
    mainWindow.Id = "MainWindow";
    mainStoLabel.Text = "#stb_entry_clah";
    

    我有两点建议。第一个是确保您总是使用/x模式,这样您就可以生成记录和可维护的正则表达式。第二个问题是,与第二个解决方案一样,一次一点点做得更干净,而不是像第一个解决方案一样。

答案 2 :(得分:1)

^[^"=]*(?<!(^|\s)readonly\s.*)\s*=\s*"[^#].*"似乎符合您的需求:

  • 第一个等号前的所有内容不应包含readonly或引号
  • readonly不识别字边界,但带有空格(行尾除外)
  • 等号可以被任意空格包围
  • 等号必须后跟带引号的字符串
  • 引用的字符串不应以#
  • 开头

如果您只想要字符串或带引号的字符串,则可以使用外观或捕获组。

注意:根据你自己的正则表达式,这会丢弃最后一个引号之后的任何内容(与示例中的分号不匹配)

答案 3 :(得分:0)

您绝对需要指定语言。负面的前瞻/外观是你需要的东西。

请查看此网站,了解如何在Delphi, GNU (Linux), Groovy, Java, JavaScript, .NET, PCRE (C/C++), Perl, PHP, POSIX, PowerShell, Python, R, REALbasic, Ruby, Tcl, VBScript, Visual Basic 6, wxWidgets, XML Schema, XQuery & XPath

中执行此操作