在分隔符之后查找单词,并忽略单词是否被大括号包围

时间:2019-06-12 23:10:56

标签: php regex find

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

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";
    }
};

2 个答案:

答案 0 :(得分:1)

重复匹配非括号字符,或者最后一个右括号后跟一个右括号。试试:

^[^=]+=(?:[^{}\n]|{[^}]+})*?respect.*$
  • ^[^=]+-从行首开始,匹配=
  • (?:[^{}\n]|{[^}]+})*?-懒洋洋地重复:
    • [^{}\n]-除{}或换行符之外的所有内容,或
    • {[^}]+}-一个{,后跟非括号字符,后跟}
  • respect-匹配您要搜索的单词
  • .*$-匹配其余行

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

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

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

答案 1 :(得分:0)

我不确定我是否正确理解了问题,但可以选择以下表达式:

\.([A-Za-z]+)\s*(?==)(?=.*\b\1\b.*).*

在这里,我们正在使用向后引用来捕获所需的工作,然后如果该词存在将获得整行内容。

Demo