Perl 兼容的正则表达式,用于测试两个单词中哪个先出现
Perl compatible regular expression to test which of two words comes first
我得到一个包含 comma-separated 单词列表的字符串(其中空格和大小写不重要),我想要一个 Perl 正则表达式来测试以下内容:该字符串包含(完整的)单词 "french" 并且(完整的)单词 "english" 没有出现在前面。例如,我想接受 "french"、"foobar, french"、"bar, french, quux, english"、"french, english, french";但拒绝 "foo, bar"、"english, french"、"foo, english, bar, french, english".
我的目标是在 lighttpd 配置中使用这种正则表达式。准确地说,我想用天真的启发式解析 Accept-Language headers,即语言按偏好降序排列,这通常是正确的,尽管 RFC 没有规定。因此,我只能有一个 Perl 兼容的正则表达式,我不能使用 Perl 的任何其他功能。
在形式语言理论中,这样的正则表达式肯定存在,但是直截了当的解决方案需要正则表达式取反,执行起来很痛苦。 (这就是为什么我用 "french" 和 "english" 而不是 "fr" 和 "en" 来问这个问题,在这种情况下,正则表达式的否定会很乏味,但可以手动完成。)是否有任何 Perl-specific 正则表达式功能可以为我的任务编写简洁的正则表达式,或者是否有自动编译正则表达式来执行此操作的工具?
像这样的东西应该可以工作
更新
在 'French' 之前的第一个 'English' 仅失败:
# /(?i)^(?:(?!\benglish\b).)*?\bfrench\b/
(?i) # Case insensitive
^ # BOS
(?:
(?! \b english \b )
.
)*?
\b french \b # 'french'
原文:
在 'French'
之前的任何 'English' 失败
# /(?i)^(?!.*\benglish\b.*\bfrench\b).*\bfrench\b/
(?i) # Case insensitive
^ # BOS
(?! # Not 'english' .. 'french'
.*
\b english \b
.*
\b french \b
)
.*
\b french \b # Must contain 'french'
我得到一个包含 comma-separated 单词列表的字符串(其中空格和大小写不重要),我想要一个 Perl 正则表达式来测试以下内容:该字符串包含(完整的)单词 "french" 并且(完整的)单词 "english" 没有出现在前面。例如,我想接受 "french"、"foobar, french"、"bar, french, quux, english"、"french, english, french";但拒绝 "foo, bar"、"english, french"、"foo, english, bar, french, english".
我的目标是在 lighttpd 配置中使用这种正则表达式。准确地说,我想用天真的启发式解析 Accept-Language headers,即语言按偏好降序排列,这通常是正确的,尽管 RFC 没有规定。因此,我只能有一个 Perl 兼容的正则表达式,我不能使用 Perl 的任何其他功能。
在形式语言理论中,这样的正则表达式肯定存在,但是直截了当的解决方案需要正则表达式取反,执行起来很痛苦。 (这就是为什么我用 "french" 和 "english" 而不是 "fr" 和 "en" 来问这个问题,在这种情况下,正则表达式的否定会很乏味,但可以手动完成。)是否有任何 Perl-specific 正则表达式功能可以为我的任务编写简洁的正则表达式,或者是否有自动编译正则表达式来执行此操作的工具?
像这样的东西应该可以工作
更新
在 'French' 之前的第一个 'English' 仅失败:
# /(?i)^(?:(?!\benglish\b).)*?\bfrench\b/
(?i) # Case insensitive
^ # BOS
(?:
(?! \b english \b )
.
)*?
\b french \b # 'french'
原文:
在 'French'
# /(?i)^(?!.*\benglish\b.*\bfrench\b).*\bfrench\b/
(?i) # Case insensitive
^ # BOS
(?! # Not 'english' .. 'french'
.*
\b english \b
.*
\b french \b
)
.*
\b french \b # Must contain 'french'