我发现这个关于正则表达式的优秀教程,虽然我直观地理解"贪婪","不情愿"和"占有欲"量词的作用,但我的理解似乎存在严重漏洞.
具体来说,在以下示例中:
Enter your regex: .*foo // greedy quantifier
Enter input string to search: xfooxxxxxxfoo
I found the text "xfooxxxxxxfoo" starting at index 0 and ending at index 13.
Enter your regex: .*?foo // reluctant quantifier
Enter input string to search: xfooxxxxxxfoo
I found the text "xfoo" starting at index 0 and ending at index 4.
I found the text "xxxxxxfoo" starting at index 4 and ending at index 13.
Enter your regex: .*+foo // possessive quantifier
Enter …Run Code Online (Sandbox Code Playgroud) 似乎使用一个字符类比一个例子中的交替更快,比如:
[abc]vs (a|b|c)
我听说它被推荐,并且使用Time::HiRes我验证的简单测试(慢10倍).在捕获括号产生差异的情况下
也使用(?:a|b|c)不会改变结果.
但我不明白为什么.我认为这是因为回溯,但我在每个位置看到它的方式有3个字符比较所以我不确定回溯是如何影响交替的.这是实施交替性质的结果吗?
我需要一个正则表达式,它只会选择那些不以 .png 或 .css 等特定扩展名结尾的 URL 字符串。
我测试了以下内容:
1)这个使用负回顾:
(?<!\.png|\.css)$
Run Code Online (Sandbox Code Playgroud)
https://regex101.com/r/tW4fO5/1
2)另一个使用负前瞻:
^(?!.*[.]png|.*[.]css$).*$
Run Code Online (Sandbox Code Playgroud)
https://regex101.com/r/qZ7vA4/1
两者似乎都工作正常,但据说 #1(负向后视)在 436 步(见链接)中处理,而 #2(负向后视)据说在 173 步中处理。
所以我的问题是:这是什么意思?会不会影响演出?
最后,这两个正则表达式在功能上真的是等价的吗?
编辑:解决方案摘要
总结一下,考虑到要通过正则表达式排除的字符串结尾的完整列表(一个典型的场景是 Web 服务器设置,其中静态资源由 apache 提供,而动态资源由不同的引擎提供 - 在我的情况下: php-fpm)。
PCRE 正则表达式有两种可能的选择:
1)负面回顾
$(?<!\.(?:ico|gif|jpg|png|css|rss|xml|htm|pdf|zip|txt|ttf)$|(?:js|gz)$|(?:html|woff)$)
https://regex101.com/r/eU9fI6/1
请注意,我使用了几个 OR ed 后视,因为负后视需要固定宽度的模式(即:您不能混合不同长度的模式)。这使得这个选项的编写稍微复杂一些。此外,在我看来,这降低了它的性能。
2)负前瞻
^(?!.*[.](?:js|ico|gif|jpg|png|css|rss|xml|htm|html|pdf|zip|gz|txt|ttf|woff)$).*$
https://regex101.com/r/dP7uD9/1
前瞻比后视略快。这是 100 万次迭代的测试结果:
后视时间 = 18.469825983047 秒
前瞻时间 = 14.316685199738 秒
如果我没有可变长度模式的问题,我会选择后视,因为它看起来更紧凑。反正哪一个都好。最后,我向前看:
<LocationMatch "^(?!.*[.](?:js|ico|gif|jpg|png|css|rss|xml|htm|html|pdf|zip|gz|txt|ttf|woff)$).*$">
SetHandler "proxy:unix:/var/run/php5-fpm.sock|fcgi://www/srv/www/gioplet/web/public/index.php"
</LocationMatch>
Run Code Online (Sandbox Code Playgroud) regex negative-lookbehind negative-lookahead regex-lookarounds
我不知道为什么,但是当我尝试运行这个程序时,看起来该程序将永远运行.
package fjr.test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test3 {
public static void main(String[] args){
String regex = "dssdfsdfdsf wdasdads dadlkn mdsds .";
Pattern p = Pattern.compile("^([a-zA-Z]+ *)+$");
Matcher match = p.matcher(regex);
if(match.matches()){
System.out.println("Yess");
}else{
System.out.println("No.. ");
}
System.out.println("FINISH...");
}
}
Run Code Online (Sandbox Code Playgroud)
我需要做的是匹配包含一串只用空格分隔的单词的模式