【问题标题】:regex search line not contain string preceding another正则表达式搜索行不包含另一个前面的字符串
【发布时间】:2014-01-17 02:43:11
【问题描述】:

我需要一个正则表达式来查找文件的行,该文件包含一个前面没有另一个字符串的字符串。

具体来说,我需要搜索包含“固定”字符串但它们在之前的任何位置都没有以“#”开头的行。例子:

fixed xxx
# fixed yyy
aaa # fixed zzz
fixed www # bbb

Regexp 应该只返回以下行:

fixed xxx
fixed www # bbb

这可以用一个正则表达式来完成吗?怎么样?

我正在使用 PHP。

谢谢大家。

PD:对不起我的英语。

【问题讨论】:

  • 正则表达式负向后查找
  • 如果fixed 应该始终位于行首,您可以使用常规字符串函数(基于示例)。

标签: php regex


【解决方案1】:

这是您需要的正则表达式(不使用任何外观):

/^[^#\n]*fixed[^\n]*$/m

解释:

^ - beginning of a line
[^#\n]* - any amount of chars that are not "#" and are not line breaks
fixed - the string itself
[^\n]* - any other characters that are not line breaks
$ - until the end of a line
/m - multiline modifier: http://php.net/manual/ro/reference.pcre.pattern.modifiers.php

在 PHP 中:

$lines = "fixed xxx\n# fixed yyy\naaa # fixed zzz\nfixed www # bbb";
$matches = array();
preg_match_all('/^[^#]*fixed.*$/m', $lines, $matches);

var_dump($matches);

结果:

array(1) {
  [0]=>
  array(2) {
    [0]=>
    string(9) "fixed xxx"
    [1]=>
    string(15) "fixed www # bbb"
  }
}

感谢@sln 的建议。

【讨论】:

  • 可能想要制作[^#] -> [^#\n] 所以它不会跨行。
  • 这是 /m 修饰符的工作
  • 并非如此。 /m 只处理 ^$。正则表达式匹配 " here is\nfixed \#"
  • php.net/manual/ro/reference.pcre.pattern.modifiers.php :设置此修饰符时,“行首”和“行尾”构造分别匹配主题字符串中的任何换行符之后或之前,以及在开始和结束
  • 这与跨度线无关。您的正则表达式匹配 "\n\n\n\nhere\n\n\nis\n\n\nan\n\n\nentire\n\n\nparagraph\n\n\n\nfixed \#" 试试看。 [^#] 也匹配换行符、cr、任何换行符。
【解决方案2】:

由于比较都是逐行进行的,我会尝试这样的事情......

(在伪代码中)

Regex regex = new Regex("^[0-9]"); //a string that starts with a number
string thisLine = input.getLine();

while(hasInput)
{
   string lastLine = thisLine;
   string thisLine = input.getLine();
   if(regex.hasMatch(lastLine)) 
   {
       System.out.println(thisLine)
   }
}

【讨论】:

    【解决方案3】:

    使用 Regex Negative Lookbehind:Live Demo

    $reg = '/(?<!\#\s)(fixed.+)/';
    
    $input = '
    fixed xxx
    # fixed yyy
    aaa # fixed zzz
    fixed www # bbb';
    
    preg_match_all($reg, $input, $output);
    $output = $output[0];
    
    print_r($output);
    

    输出:

    Array
    (
        [0] => fixed xxx
        [1] => fixed www # bbb
    )
    

    【讨论】:

      【解决方案4】:

      这种方法从行尾检查到开头。
      万一fixed # fixed

       #  '/^(?!.*\#.*fixed).*fixed.*/m'
      
       ^ 
       (?! .* \# .* fixed )
       .* 
       fixed
       .* 
      

      【讨论】:

        【解决方案5】:

        或消极的后视方式:

        (?<!#\s)fixed.*
        

        例子:

        http://regex101.com/r/rR4eG1

        PHP:

        $string = "fixed xxx
        # fixed yyy
        aaa # fixed zzz
        fixed www # bbb";
        
        preg_match_all("/(?<!#\s)fixed.*/", $string, $matches);
        
        print_r($matches);
        

        输出:

        Array
        (
            [0] => Array
                (
                    [0] => fixed xxx
                    [1] => fixed www # bbb
                )
        )
        

        【讨论】:

          猜你喜欢
          • 2023-03-26
          • 1970-01-01
          • 1970-01-01
          • 2021-04-24
          • 2015-06-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-08
          • 2019-09-25
          相关资源
          最近更新 更多