我有一个代码块,其中包含很多条件中包含“contains()”的条件。我正在尝试使用正则表达式这么容易,但渲染时需要花费很多时间(SocketTimeoutException
)。
旧代码:
if (!url.toLowerCase().contains("wikipedia")
&& !URL.toLowerCase().contains("vikidia")
&& !URL.toLowerCase().contains("wikimini")
&& !URL.toLowerCase().contains("dictionnaire")
&& !URL.toLowerCase().contains("dictionary")
&& !URL.toLowerCase().contains("traduction")
&& !URL.toLowerCase().contains("wiktionary")
&& !URL.toLowerCase().contains("academia.edu")
&& !URL.toLowerCase().contains("about.me")
&& !URL.toLowerCase().contains("facebook")
&& !URL.toLowerCase().contains("linkedin")
&& !URL.toLowerCase().contains("viadeo")
&& !URL.toLowerCase().contains("flickr")
&& !URL.toLowerCase().contains("google+")
&& !URL.toLowerCase().contains("plus.google")
&& !URL.toLowerCase().contains("instagram")
&& !URL.toLowerCase().contains("linkedin")
&& !URL.toLowerCase().contains("netlog")
&& !URL.toLowerCase().contains("orkut")
&& !URL.toLowerCase().contains("pinterest")
&& !URL.toLowerCase().contains("twitter")
&& !URL.toLowerCase().contains("tripadvisor")
&& !URL.toLowerCase().contains("youtube")
&& !URL.toLowerCase().contains("vimeo")
&& !URL.toLowerCase().contains("dailymotion")
&& !URL.toLowerCase().contains("pagesjaunes")
&& !URL.toLowerCase().contains("indeed")
&& !URL.toLowerCase().contains("jobteaser.com")
&& !URL.toLowerCase().contains("mappy.com")
&& !URL.toLowerCase().contains("slideshare")
&& !URL.toLowerCase().contains("meteofrance.com")
&& !URL.toLowerCase().contains("linternaute.com")
&& !URL.toLowerCase().contains("news.google")
&& !URL.toLowerCase().contains("persee.fr") // portail de revues en sciences humaines et sociales
&& !URL.toLowerCase().contains("/downloads") // the url for downloading
&& !URL.toLowerCase().contains("/streaming")
&& !URL.toLowerCase().contains("http://stackoverflow.com/")
&& !URL.endsWith("pdf")
&& !URL.endsWith("txt")
&& !URL.endsWith("ps")
&& !URL.endsWith("dwf")
&& !URL.endsWith("klm")
&& !URL.endsWith("kmz")
&& !URL.endsWith("xls")
&& !URL.endsWith("xlsx")
&& !URL.endsWith("ppt")
&& !URL.endsWith("pptx")
&& !URL.endsWith("doc")
&& !URL.endsWith("docx")
&& !URL.endsWith("rtf")
&& !URL.endsWith("swf")
&& !URL.contains(".en.")
&& !URL.contains("/en/")
&& !URL.contains("/en.")
&& !URL.contains("books.")
&& !URL.contains("forum.")
&& !URL.contains("forum")
&& !URL.contains("blog.")
&& !URL.contains("infogreffe.fr/") //to test
&& !URL.contains("bing.com/images")) {
if (!URL.matches(".*\\btraduction\\b.*")) {
...
}
反应一:
if (!URL.toLowerCase().matches("^.*(wikipedia|vikidia|wikimini|dictionnaire|dictionary|traduction|wiktionary|(academia.edu)|(about.me)|facebook|linkedin|viadeo|flickr|(google+)|instagram|(plus.google)|linkedin|netlog|orkut|pinterest|twitter|tripadvisor|youtube|(vimeo+)|dailymotion|pagesjaunes|indeed|(jobteaser.com)|(mappy.com)|slideshare|(meteofrance.com)|(linternaute.com)|(news.google)|(persee.fr)|(/downloads)|(/streaming)|(stackoverflow.com)|pdf|txt|ps|dwf|klm||xls|xlsx|ppt|pptx|doc|docx|rtf|swf|(.en.)|(/en/)|(books.)|(forum.)|(blog.)|(infogreffe.fr/)|(bing.com/images)).*$")
) {...}
你有没有更好的想法重构旧的。非常感谢你
答案 0 :(得分:1)
我可以提出一个建议,至少可以帮助部分解决有关URL结尾的逻辑。您可以将URL的结尾提取为字符串。然后,创建一个包含列入黑名单的字符串的地图,如下所示:
String URLend = "some_value";
Map<String, Integer> map = new HashMap<>();
map.put("pdf", 1);
map.put("txt", 1);
map.put("ps", 1);
map.put("dwf", 1);
// and other terms...
现在,您可以轻松检查网址末尾是否与列入黑名单的字词匹配:
if (map.get(URLend) != null) {
// then the URL is blacklisted
}
这里的优点是查找时间是恒定的,比冗长的正则表达式快得多。缺点是这只会覆盖你需要比较的整个字符串的逻辑,这不能完全解决你的问题。
答案 1 :(得分:0)
首先,基于正则表达式的解决方案很慢的最可能原因是您使用.*
和matches
。问题是*
是贪婪的,所以它会尝试匹配尽可能多的字符。这意味着在找到匹配项之前会有很多回溯跟踪。在模式不匹配的情况下甚至更多的回溯。
使用Matcher::find
可能会获得更好的性能,并摆脱.*
子模式。
通过分解String::contains
调用,您在使用toLowerCase
的代码中也可以获得更好的性能。当然代码会更具可读性。
但如果您真的担心性能问题,我认为您应该研究像Rabin-Karp algorithm这样的快速字符串搜索算法。 (处理&#34;以&#34结尾;单独搜索。)
答案 2 :(得分:0)
您可以将“contains”和“endsWith”测试组合成一个正则表达式。
如果匹配,则测试失败。
只需要一点点重构,而且速度非常快。
(?i)(?:^.*(d(?:ocx?|wf)|k(?:lm|mz)|p(?:df|ptx?|s)|(?:rt|sw)f|txt|xlsx?)\s*$|(\.en\.|/(?:downloads|en[./]|streaming)|a(?:bout\.me|cademia\.edu)|b(?:ing\.com/images|(?:log|ooks)\.)|d(?:ailymotion|iction(?:ary|naire))|f(?:acebook|lickr|orum\.?)|google\+|http://stackoverflow\.com/|in(?:deed|fogreffe\.fr/|stagram)|(?:jobteaser|m(?:appy|eteofrance))\.com|lin(?:kedin|ternaute\.com)|ne(?:tlog|ws\.google)|orkut|p(?:agesjaunes|ersee\.fr|interest|lus\.google)|(?:slideshar|youtub)e|t(?:r(?:aduction|ipadvisor)|witter)|vi(?:(?:ad|m)eo|kidia)|wik(?:imini|tionary)))
https://regex101.com/r/7sS4ek/1
(?i)
(?:
# endsWith
^
.*
( # (1 start)
d
(?: ocx? | wf )
| k
(?: lm | mz )
| p
(?: df | ptx? | s )
| (?: rt | sw )
f
| txt
| xlsx?
) # (1 end)
\s*
$
|
# contains
( # (2 start)
\. en \.
| /
(?: downloads | en [./] | streaming )
| a
(?: bout \. me | cademia \. edu )
| b
(?:
ing \. com/images
| (?: log | ooks )
\.
)
| d
(?:
ailymotion
| iction
(?: ary | naire )
)
| f
(?: acebook | lickr | orum \.? )
| google \+
| http://stackoverflow \. com/
| in
(?: deed | fogreffe \. fr/ | stagram )
| (?:
jobteaser
| m
(?: appy | eteofrance )
)
\. com
| lin
(?: kedin | ternaute \. com )
| ne
(?: tlog | ws \. google )
| orkut
| p
(?:
agesjaunes
| ersee \. fr
| interest
| lus \. google
)
| (?: slideshar | youtub )
e
| t
(?:
r
(?: aduction | ipadvisor )
| witter
)
| vi
(?:
(?: ad | m )
eo
| kidia
)
| wik
(?: imini | tionary )
) # (2 end)
)