java - Java 正则表达式与 PHP,悬空元字符“?”
问题描述
即使这是一个 Java 问题,我也用 PHP 来标记它。正则表达式是从 PHP 源复制的,所以我希望一些 PHPers 可以帮助解决这个问题。
我决定构建一个简单的垃圾邮件过滤器,只是为了好玩,我从 MediaWiki 复制了垃圾邮件阻止列表:https ://meta.wikimedia.org/wiki/Spam_blacklist
大多数情况下,这似乎有效,但一些模式因语法错误而失败。我不知道这是一个错字还是 PHP 使用的语法与 Java 不同。谁能帮我修复这些正则表达式以便它们编译?
以下是问题:
java.util.regex.PatternSyntaxException: Dangling meta character '?' near index 17
\bfacebo(?:o[ob]|?o)k\.com\b
^
java.util.regex.PatternSyntaxException: Dangling meta character '?' near index 5
\b????\.tk\b
^
java.util.regex.PatternSyntaxException: Dangling meta character '?' near index 0
??\.xsl\.pt\b
^
java.util.regex.PatternSyntaxException: Dangling meta character '?' near index 4
\b????\.shop\b
^
java.util.regex.PatternSyntaxException: Dangling meta character '?' near index 4
\b???\.??\b
^
如果您有兴趣,这是编译它们的代码。我不认为这有什么不同。
private static synchronized void init() throws IOException {
if( blackListPatterns.get() != null ) return;
InputStream blacklistfile = SpamBlackList.class.getResourceAsStream( "blacklist.txt" );
BufferedReader buf = new BufferedReader( new InputStreamReader( blacklistfile, "UTF-8" ) );
ArrayList<String> blacklist = new ArrayList<>( 12000 );
for( String line; (line = buf.readLine()) != null; )
if( !line.isBlank() && line.trim().charAt(0) != '#' )
blacklist.add( line );
ArrayList<Pattern> tempPatterns = new ArrayList<>( blacklist.size() );
for( String pat : blacklist )
try {
tempPatterns.add( Pattern.compile( pat ) );
} catch ( java.util.regex.PatternSyntaxException ex ) {
System.err.println( ex ); // should log this, low level like FINER
}
blackListPatterns = new WeakReference<>( tempPatterns );
}
private static volatile WeakReference<List<Pattern>>
blackListPatterns = new WeakReference( null );
解决方案
您下载的https://meta.wikimedia.org/wiki/Spam_blacklist ( )副本blacklist.txt
已损坏。悬空的问号是非 ASCII 字符,例如\bfacebo(?:o[ob]|?o)k\.com\b
is 实际上\bfacebo(?:o[ob]|ıo)k\.com\b
。请注意无点的“ı”。
下载https://meta.wikimedia.org/wiki/Spam_blacklist?action=raw并考虑到它是 UTF-8。
您可能希望将 Unicode 标志传递给正则表达式。还要考虑到:
这里所说的正则表达式不是正确的正则表达式,而是插入到硬编码的正则表达式中的子模式。即上面的子模式Foo 将创建一个像/^Foo$/usi 这样的正则表达式。
(见https://www.mediawiki.org/wiki/Extension:TitleBlacklist#Block_list)。
推荐阅读
- node.js - 安装 React 开关输入的问题
- swift - String.init 期间发生了什么
- postgresql - 错误:无法在 IntelliJ IDEA 中使用 PostgreSQL 的只读事务中执行更新
- javascript - 成功禁止某人时,Discord Bot 意外退出并出现错误
- python - How to break the loop in Python?
- performance - 如何让这个谷歌脚本更高效
- python - Python请求不重定向
- postgresql - java.sql.SQLException:无法加载 JDBC 驱动程序类“org.postgresql.Driver”
- python - 从 django 上的网站下载文件
- android - Jetpack Compose 中带有分页库的粘性标头