正则表达式用正斜杠分割
我有一个包含一些信息的解析树。 为了提取我需要的信息,我使用了一个基于正斜杠( /
)分割字符串的代码,但这不是一个完美的代码。 我在这里解释更多细节:
我早些时候在另一个项目中使用过这些代码,并且工作完美。 但是现在我的新数据集的解析树更加复杂,有时代码会做出错误的决定。
解析树是这样的:
(TOP~did~1~1 (S~did~2~2 (NPB~I~1~1 I/PRP ) (VP~did~3~1 did/VBD not/RB (VP~read~2~1 read/VB (NPB~article~2~2 the/DT article/NN ./PUNC. ) ) ) ) )
如你所见,树的叶子是正斜线之前的词。 为了得到这些单词,我以前使用过这些代码:
parse_tree.split("/");
但是现在,在我的新数据中,我看到了这样的例子:
1) (TOP Source/NN http://www.alwatan.com.sa/daily/2007-01-31/first_page/first_page01.htm/X ./. )
由于网站地址有多个斜杠(在这种情况下,只有最后一个斜杠是该词的分隔符)。
2) (NPB~sister~2~2 Your/PRP$ sister/NN //PUNC: )
斜线本身就是一个词。
你能帮我用一个可以管理这些情况的表达式替换我目前简单的正则表达式吗?
为了总结我需要的东西,我会说我需要一个正则表达式,它可以基于正斜杠进行拆分,但它必须能够管理两个例外:1)如果有网站地址,则必须根据最后一个斜杠进行拆分。 2)如果有两个连续的斜线,它必须基于第二个分割进行分割(并且第一个斜线不能被视为分隔符,它是一个WORD)。
我在这篇文章后达到了你所要求的:
http://www.rexegg.com/regex-best-trick.html
总而言之,以下是总体战略:
第一,你需要用这种格式创建一个正则表达式:
NotThis | NeitherThis | (IWantThis)
之后,您的捕获组$ 1将只包含您有兴趣执行拆分的斜杠。
然后,您可以将它们替换为不太可能发生的事情,然后在此替换的术语中执行拆分。
所以,考虑到这个策略,下面是代码:
正则表达式:
/(?=/)|(?:http://)?www[w./-]*(?=/)|(/)
说明:
不是这个词将会是前瞻性的双斜线(只取第一斜线)
/(?=/)
Neither这个术语只是一个基本的URL检查,向前看不到最后一个 /
(?:http://)?www[w./-]*(?=/)
IWant这个术语简直就是斜线:
(/)
在Java代码中,你可以把它们放在一起做这样的事情:
Pattern p = Pattern.compile("/(?=/)|(?:http://)?www[w./-]*(?=/)|(/)");
Matcher m = p.matcher("(TOP~did~1~1 (S~did~2~2 (NPB~I~1~1 I/PRP ) (VP~did~3~1 did/VBD not/RB (VP~read~2~1 read/VB (NPB~article~2~2 the/DT article/NN ./PUNC. ) ) ) ) )n(TOP Source/NN http://www.alwatan.com.sa/daily/2007-01-31/first_page/first_page01.htm/X ./. )n(NPB~sister~2~2 Your/PRP$ sister/NN //PUNC: )");
StringBuffer b= new StringBuffer();
while (m.find()) {
if(m.group(1) != null) m.appendReplacement(b, "Superman");
else m.appendReplacement(b, m.group(0));
}
m.appendTail(b);
String replaced = b.toString();
System.out.println("n" + "*** Replacements ***");
System.out.println(replaced);
String[] splits = replaced.split("Superman");
System.out.println("n" + "*** Splits ***");
for (String split : splits) System.out.println(split);
输出:
*** Replacements ***
(TOP~did~1~1 (S~did~2~2 (NPB~I~1~1 ISupermanPRP ) (VP~did~3~1 didSupermanVBD notSupermanRB (VP~read~2~1 readSupermanVB (NPB~article~2~2 theSupermanDT articleSupermanNN .SupermanPUNC. ) ) ) ) )
(TOP SourceSupermanNN http://www.alwatan.com.sa/daily/2007-01-31/first_page/first_page01.htmSupermanX .Superman. )
(NPB~sister~2~2 YourSupermanPRP$ sisterSupermanNN /SupermanPUNC: )
*** Splits ***
(TOP~did~1~1 (S~did~2~2 (NPB~I~1~1 I
PRP ) (VP~did~3~1 did
VBD not
RB (VP~read~2~1 read
VB (NPB~article~2~2 the
DT article
NN .
PUNC. ) ) ) ) )
(TOP Source
NN http://www.alwatan.com.sa/daily/2007-01-31/first_page/first_page01.htm
X .
. )
(NPB~sister~2~2 Your
PRP$ sister
NN /
PUNC: )
您应该能够使用正反面的负面后视。 这需要更大范围的输入样本,但似乎适用于以下两种情况:
String pattern = "(?<![:/])/";
String s1 = "(TOP Source/NN http://www.alwatan.com.sa/daily/2007-01-31/first_page/first_page01.htm/X ./. )";
List<String> a = (List<String>) Arrays.asList(s1.split(pattern));
System.out.println("first case:");
System.out.println(a.stream().map(i->i.toString()).collect(Collectors.joining(",n")));
System.out.println("n");
String s2 = "(NPB~sister~2~2 Your/PRP$ sister/NN //PUNC: )";
a = (List<String>) Arrays.asList(s2.split(pattern));
System.out.println("second case");
System.out.println(a.stream().map(i->i.toString()).collect(Collectors.joining(",n")));
这输出:
first case:
(TOP Source,
NN http://www.alwatan.com.sa,
daily,
2007-01-31,
first_page,
first_page01.htm,
X .,
. )
second case
(NPB~sister~2~2 Your,
PRP$ sister,
NN ,
/PUNC: )
进一步过滤你的匹配,不包括正确匹配的正则表达式匹配任何url http / https / ftp,你可以包括尽可能多的协议
(?<protocol>http(s)?|ftp)://(?<server>([A-Za-z0-9-]+.)*(?<basedomain>[A-Za-z0-9-]+.[A-Za-z0-9]+))+ ((/?)(?<path>(?<dir>[A-Za-z0-9._-]+)))*
and then match instances of multiple slashes with (/)+
the'+' here is a greedy match which means it will match as many consecutive slashes as it can whether it be // // or //
希望这可以帮助
链接地址: http://www.djcxy.com/p/84991.html