Perl兼容正则表达式来测试两个单词中的哪一个首先出现

时间:2015-01-05 17:57:38

标签: regex perl

我得到一个包含以逗号分隔的单词列表的字符串(其中空格和大小写不重要)我想要一个Perl正则表达式来测试以下内容:字符串包含(完整)单词" french&# 34;和(完整的)单词"英语"不会提前发生。例如,我想接受" french"," foobar,french"," bar,french,quux,english"," french,english,法国&#34 ;;但拒绝" foo,bar","英语,法语"," foo,英语,酒吧,法语,英语"。

我的目标是在lighttpd配置中使用此类正则表达式。确切地说,我想解析Accept-Language标题,使用天真的启发式方法,语言以递减的优先顺序列出,尽管RFC没有规定,但这通常是正确的。因此,我只能使用Perl兼容的正则表达式,我不能使用Perl的任何其他功能。

就形式语言理论而言,必须存在这样的正则表达式,但直接的解决方案需要正则表达式否定,这很难执行。 (这就是为什么我问"法语"和#34;英语"而不是" fr"和#34; en",其中regexp否定会虽然很乏味但可以手工操作。)是否有任何Perl特定的正则表达式功能可以为我的任务编写简洁的正则表达式,或者是否有工具自动编译正则表达式来执行此操作?

1 个答案:

答案 0 :(得分:1)

这样的事情应该有效

<强>更新
在“法语”之前首先“英语”失败:

 # /(?i)^(?:(?!\benglish\b).)*?\bfrench\b/

 (?i)                          # Case insensitive
 ^                             # BOS
 (?:
      (?! \b english \b )
      . 
 )*?
 \b french \b                  # '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'