我几乎不好意思问,但差不多。我似乎有一个已经有效的表达式,但它似乎只适用于各种正则表达式工具,如Regulator或在线工具。一旦进入我的C#代码,它就无法达到应有的位置。
所以问题是我需要正则表达式来命中包含“android”,“iphone”或“ipod”的用户代理字符串,而不是那些也包含“opera”的用户代理字符串。很简单,对吧?
到目前为止,我已经有了这个:
^(?=.*?\b(android|iphone|ipod)\b)(?!opera).*$
我正在使用以下选项
RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Singleline
请告诉我哪里弄错了。
以下是一些用户代理字符串。表达式应该在第一个和最后一个触发,而忽略中间的两个:
Mozilla/5.0+(Linux;+U;+Android+2.2;+nb-no;+Nexus+One+Build/FRF91)+AppleWebKit/533.1+(KHTML,+like Gecko)+Version/4.0+Mobile+Safari/533.1
Opera/9.80 (Android; Linux; Opera Mobi/ADR-1012221546; U; pl) Presto/2.7.60 Version/10.5
Opera/9.80 (J2ME/iPhone;Opera Mini/5.0.019802/886; U; ja)Presto/2.4.15
Mozila/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Geckto) Version/3.0 Mobile/3A101a Safari/419.3
由于
答案 0 :(得分:5)
您是否记得在模式字符串前添加“@”?如果不是,“\ b”将被解释为退格。
另外有些人说,你不是在任何地方检查Opera,而是在行的开头,这是故意的吗?我可能会使用这种语法:
@"^(?!opera)(?=.*\b(android|iphone|ipod)\b).*$"
答案 1 :(得分:1)
Negative look-aheads are tricky。简而言之,你只是拒绝字符串开头不包含opera的字符串(更正后,感谢@stema)。老实说,为了防止经常与前瞻相关的混乱,你可能想把它分成两部分:
选项1:
使用不带前瞻的正则表达式,加上String.Contains()
Regex myRegex =“(?i)(android | iphone | ipod)”; //不区分大小写
bool isUserStringNonOperaMobile = myRegex.isMatch(userString)&& !userString.ToLower()包含( “歌剧”);
选项2:
使用两个正则表达式
Regex myRegex =“(?i)(android | iphone | ipod)”; //不区分大小写
Regex myOtherRegex =“(?i)歌剧”; //不区分大小写
bool isUserStringNonOperaMobile = myRegex.isMatch(userString)&& !myOtherRegex.isMatch(userString);
是的,这些可能效率稍低,但可忽略不计,效率损失,可读性和可维护性都会提高。
答案 2 :(得分:1)
您只在字符串的最开头检查opera
。那是为了吗?
每一次展望都试图从一开始就匹配。您将其绑定到^
,然后您的前瞻只有opera
,之前不允许其他字符。
尝试
^(?=.*?\b(android|iphone|ipod)\b)(?!.*opera).*$
检查字符串中某处的opera
。
答案 3 :(得分:-1)
我不熟悉c#,但你确定它支持?!
构造吗?