许多现代正则表达式实现将\w字符类简写解释为"任何字母,数字或连接标点符号"(通常为下划线).这样一来,像一个正则表达式\w+像火柴的话hello,élève,GOÄ_432或gefräßig.
不幸的是,Java没有.在Java中,\w仅限于[A-Za-z0-9_].这使得像上述那些匹配的单词难以解决.
似乎\b单词分隔符在不应该的位置匹配.
什么是类似.NET,Unicode感知\w或\bJava 的正确等价物?哪些其他快捷方式需要"重写"以使其具有Unicode感知功能?
我刚刚看到Java的一个巨大的正则表达式让我想到了一般的正则表达式的可维护性.我相信大多数人 - 除了一些坏蛋perl贩子 - 会同意正则表达式难以维持.
我在考虑如何解决这种情况.到目前为止,我最有希望的想法是使用流畅的界面.举个例子,而不是:
Pattern pattern = Pattern.compile("a*|b{2,5}");
Run Code Online (Sandbox Code Playgroud)
一个人可以写这样的东西
import static util.PatternBuilder.*
Pattern pattern = string("a").anyTimes().or().string("b").times(2,5).compile();
Pattern alternative =
or(
string("a").anyTimes(),
string("b").times(2,5)
)
.compile();
Run Code Online (Sandbox Code Playgroud)
在这个非常简短的例子中,创建正则表达式的常用方法对于任何平庸的有才华的开发人员来说仍然是可读的.但是,请考虑那些填充两行或更多行的怪异表达式,每行包含80个字符.当然,(冗长)流畅的界面需要几行而不是只有两行,但我相信它会更具可读性(因此可维护).
现在我的问题:
你知道正则表达式的任何类似方法吗?
你是否同意这种方法比使用简单的字符串更好?
你会如何设计API?
你会在你的项目中使用这样一个整洁的实用程序吗?
你认为这会很有趣吗?;)
编辑: 想象一下,可能存在比简单构造更高级别的方法,我们都没有来自正则表达式,例如
// matches aaaab@example.com - think of it as reusable expressions
Pattern p = string{"a").anyTimes().string("b@").domain().compile();
Run Code Online (Sandbox Code Playgroud)
编辑 - 评论的简短摘要:
RegexBuddy - 花30欧元让你的代码可读(wtf?!这种产品的纯粹存在证明了我的论文是正确的 - 我们今天所知道的正则表达式是坏事(tm))
Martin Fowler的方法(仍然远非完美)
有趣的是,大多数人都认为正则表达式仍然存在 - 虽然它需要工具来阅读它们,聪明的家伙想办法让它们可维护.虽然我不确定流畅的界面是最好的方法,但我确信有些聪明的工程师 - 我们呢?;) - 应该花一些时间让正则表达式成为过去 - 这已经足够让他们和我们在一起已有50年了,你不觉得吗?
开放的BOUNTY
对于正则表达式的新方法,赏金将被授予最佳想法(无需代码).
编辑 - 一个很好的例子:
这是我正在谈论的那种模式 - 对能够翻译它的第一个人的额外荣誉 …
我有一个类似模式的长htdoc,继续这样:
<td class="MODULE_PRODUCTS_CELL " align="center" valign="top" height="100">
<table width="100" summary="products"><tr>
<td align="center" height="75">
<a href="/collections.php?prod_id=50">
<img src="files/products_categories50_t.txt" border="0" alt="products" /></a><\br>
</td>
</tr>
<tr>
<td align="center">
<a href="/collections.php?prod_id=50"><strong>Buffer</strong><br />
</a>
<td>
</tr></table>
</td>
Run Code Online (Sandbox Code Playgroud)
在上面的html中我想提取:
collections.php?prod_id=50 files/products_categories50_t.txtBuffer我已经尝试过这段代码,
#!/usr/local/bin/perl
use strict;
use warnings;
my $filename = 'sr.txt';
open(FILENAME,$filename);
my @str = <FILENAME>;
chomp(@str);
#print "@str";
foreach my $str(@str){
if ($str =~/<td class(.*)<a href(.*?)><\/td>/) {
print "*****$2\n";
}
}
Run Code Online (Sandbox Code Playgroud)
此代码是试用版.然而,它只带来最后一次出现,而不是每次出现.为什么?