首页 > 解决方案 > 在分隔符后查找单词,如果单词被大括号包围,则忽略

问题描述

我有一个由 (=) 等号分隔的语言变量列表。示例列表:

global.second = second 
global.minute = minute
global.respect = respect
global.Respect = Respect
respect.count = You have # ${global.respect}
give.respect = Get more ${global.respect} by giving others respect.
give.Respect = Get more ${global.Respect} by giving others Respect.

我一直在努力使用正则表达式,因为如果 (=) 等号后的特定单词存在,我需要捕获整行,如果单词在大括号中,则忽略,但如果该单词之后存在,仍会捕获整行那是在大括号中。

使用示例列表并搜索尊重

IGNORE: global.second = second 
IGNORE: global.minute = minute
CAPTURE LINE: global.respect = respect
CAPTURE LINE: global.Respect = Respect
IGNORE: respect.count = You have # ${global.respect}
CAPTURE LINE: give.respect = Get more ${global.respect} by giving others respect.
CAPTURE LINE: give.Respect = Get more ${global.Respect} by giving others Respect.

使用 google 和 stackoverflow 我想出了以下正则表达式:

/((?!\{[^\}]*?)(respect)(?![^\{]*?}))$/mi

但它不起作用,因为它只获得尊重尊重

为了捕获整行,我将其修改为

^(.*=.*?)((?!\{[^\}]*?)(respect)(?![^\{]*?}))$

但它仍然只捕获:

global.respect = respect
global.Respect = Respect

我是正则表达式新手,我不知道如何制作这个复杂的正则表达式。如果有人可以提供帮助,将不胜感激!我在“显示一些代码”中添加了我的 php 过滤器功能。$search_word 来自我的一个页面中的输入文本框。

function FilterWord($search_word, $main_file_path, $filter_file_path)
{
    $content = file_get_contents($main_file_path);
    $pattern = preg_quote($search_word, '/');
    //$pattern = "/^.*=.*$pattern.*\$/mi";
    $pattern = "/(.*=.*?)((?!\{[^\}]*?)($pattern)(?![^\{]*?}))$/mi";
    //[^$search_word {}]+(?![^{]*})
    //$pattern = "/^.*=.*$pattern.*\$/mi";
    //"/^.*=.*(!\$*.$pattern.*)($pattern.*)\$/m";
    //$pattern = "/^.*=.*(?!\{.*$pattern.*\}*?)($pattern.*)\$/m";
    //((?!\{[^\}]*?)(kudo)(?![^\{]*?}))
    //$pattern = "/(.*=.*?)(?:(?!\{[^\}]*?)\b)($search_word)(?:\b(?![^\{]*?\}))\$/mi";
    if(preg_match_all($pattern, $content, $matches)){
        file_put_contents($filter_file_path, implode("\n", $matches[0]));
    }
    else{
        echo "No matches found";
    }
};

标签: phpregexfind

解决方案


重复匹配非括号字符,或左括号最终后跟右括号。尝试:

^[^=]+=(?:[^{}\n]|{[^}]+})*?respect.*$
  • ^[^=]+- 从行首开始,匹配除 a 之外的任何内容=
  • (?:[^{}\n]|{[^}]+})*?- 懒惰地重复:
    • [^{}\n]- 除了{, }, 或换行符之外的任何内容,或
    • {[^}]+}- A {,后跟非括号字符,后跟}
  • respect- 匹配您正在搜索的单词
  • .*$- 匹配线路的其余部分

https://regex101.com/r/E8lQx5/1

请注意,由于{and}通常不是正则表达式中的特殊字符,因此它们不需要转义(除非{}s 可以解释为量词,这里不是这种情况)。

如果您愿意,您可以使用原子组使其效率更高一些,以避免在模式已经确定在该位置失败时回溯 - 使用(?>而不是(?:.


推荐阅读