如何避免可能会或不会出现/干扰正则表达式的字符组?

时间:2014-01-29 14:19:34

标签: regex perl

我正在经历一些带有正则表达的波纹地毯盒。

正在处理的原始表单中的字符串如下所示:

1. [8] S Wawrinka (SUI) vs. A Golubev (KAZ)  2. D Sela (ISR) vs. J Nieminen (FIN)  3. S Giraldo (COL) vs. S Querrey (USA)  4. A Falla (COL) vs. M Kukushkin (KAZ)  5. I Karlovic (CRO) vs. [32] I Dodig (CRO)  6. [WC] S Johnson (USA) vs. A Mannarino (FRA)  7. [14] M Youzhny (RUS) vs. JL Struff (GER)  8. A Gonzalez (COL) vs. [3] D Ferrer (ESP)  9. [7] T Berdych (CZE) vs. A Nedovyesov (KAZ)  10. N Mahut (FRA) vs. M Ebden (AUS)H2H RR2*  11. [Q] D Thiem (AUT) vs. J Sousa (POR)  12. J Monaco (ARG) vs. [23] E Gulbis (LAT)  13. J Hajek (CZE) vs. [Q] D Dzumhur (BIH)

我并不是想让它尽可能地难以阅读,但这是从HTML中吐出的确切输出。 我想要匹配的是这个(例如上述输出):

 S Wawrinka (SUI) vs. A Golubev (KAZ)

 I Karlovic (CRO) vs. I Dodig (CRO)

 J Hajek (CZE) vs. D Dzumhur (BIH)

请注意,在过去两年中,我不得不对一些括号中的char组进行一些清理。

所以基本上我想要在这个长字符串中包含所有记录。 (记录是通过对比来识别的,所以如果该字符串中有12个对应的那么应该有12个记录。(它们在两侧的预期输出中匹配,这样这部分就不用担心了我的)

在我展示的3个例子中,我给出了我试图忽略的例子。可能出现的我试图避免的字符放在vs的任何一侧的一对括号中,并且是:([WC],[Q],[LL],[12],[1], [28])

永不改变的事情:

  • VS。保证每个记录都在那里
  • 垃圾字符总是在括号中,并显示在任一名称之前
  • 整体记录始终保持格式

可能使匹配变得棘手的原因是初始值可能与其中一个垃圾字符(Q,W)相同。

我已经尝试了几个表达式,几乎所有表达式都只能实现部分匹配,这与任何表达式一样好。也许最成功的是:

       qr /
        ([A-Z]{1,2}   # Initials
        \s?
        [A-Za-z\']+   # Last name
        -?            # in case of hyphenated name
        \s?
        [A-Za-z\.]?   # two namer
        \s?
        \([A-Z]{3}\)  # country code
        \s?
        vs[.]?        # vs.
        \s?
        [^\]]\]?      # optional unwanted characters
        \s?
        [A-Z]{1,2}    
        \s?
        [A-Za-z\']+
        -?
        \s?
        [A-Za-z\.]*
        \s?
        \([A-Z]{3}\))
        /sx

我几乎可以匹配所有内容,然后只是清理我不想要的东西,但我想要一次性的清洁解决方案。

3 个答案:

答案 0 :(得分:1)

我建议您使用以下算法:

  1. 按照模式[0-9]+\.拆分字符串。这将为您提供所有记录。 (你必须丢弃第一个空项目。)
  2. 按字符串vs.拆分每个项目。这将给你们两个参赛者。
  3. 使用更简单的正则表达式解析每个参赛者的姓名,国家等。

答案 1 :(得分:1)

一种方法是摆脱分散注意力的东西:

# $t = "1. [8] S Waw....
my $re_name = qr/\b\w \w+ [(]\w+[)]/;
$t =~ s/\[[^\]]*\]//g; $t =~ s/ +/ /g;  # remove squared stuff
print "$1 vs. $2\n" while $t =~ /($re_name) vs[.] ($re_name)/g;

答案 2 :(得分:0)

退出尝试将其塞进一个语句中。 因为你不关心括号内的信息,只需用替代操作来破坏     小号/\[.*?\]//克; 首先,然后拆分     / \ d + \ ./