我正在尝试编写一个正则表达式,用于在纯文本中匹配法律案例名称的Ruby程序。
我提出了以下正则表达式:
((([[:upper:]])+\s)?((([[:upper:]]+([[:lower:]])+)\s)+v\s((\b[[:upper:]]([[:lower:]])+)\s?)+(\(|\[)+\d+(\)|\])\s(\d+\s)?\w+\s(\w+)?(\s)?(\d+)?))
这几乎可以满足我的需要但是有些边缘情况无法匹配。我需要一个符合以下情况的表达式(包括最后的引用):
Seele Austria GmbH& Co v Tokyo Marine Europe Insurance Ltd [2009] EWHC 2066
Darlington Building Society v O&#; Rourke James Scourfield&麦卡锡[1999] PNLR 365
我所写的表达方式的基础是法律案例标题将是一系列标题案例词,中间有一个v。然而,上述两个示例中的&符号与示例1中的有限责任公司一起放弃了我只得到了一些部分匹配(来自Co v ...)对1.我根本没有匹配。< / p>
如果有人可以告诉我如何改变我的表达方式以符合上述两个例子,我会很感激。表达也很笨拙 - 也许它可以简化?
答案 0 :(得分:1)
CASE_REGEXP = %r{
(?<spaces> \s+ ){0}
(?<capword> [[:upper:]] [[:alpha:]']+ ){0}
(?<titleword> \g<capword> | & ){0}
(?<title> \g<capword> (?:\g<spaces> \g<titleword>)* ){0}
(?<year> \[ \d{4} \] | \( \d{4} \) ){0}
(?<endbit> [[:upper:]]+ \g<spaces> \d+ ){0}
\g<title> \g<spaces> v \g<spaces> \g<title>
\g<spaces> \g<year>
\g<spaces> \g<endbit>
}x
Ruby的Oniguruma非常强大,即使你需要更复杂的东西,也能让你写出非常清晰的正则表达式。
编辑:忘了这一年,最后还有其他什么。稍微修复一下。EDIT2:补充道。
答案 1 :(得分:0)
这是我提出的匹配两种情况的方法。
(([A-Z]('[A-Z]|[a-z][A-Z])?[a-z]+[A-Z]?|&)\s)+(v\s)(([A-Z]('[A-Z]|[a-z][A-Z])?[a-z]+[A-Z]?|&)\s)+\[\d{4}\]\s[A-Z]+\s\d+
这是故障
(([A-Z]('[A-Z]|[a-z][A-Z])?[a-z]+[A-Z]?|&)\s)+
这将匹配&
以及Adam
,O'Neal
,McCarthy
等字词,它会考虑名称的不同情况。
(v\s)
这将匹配字母v
后跟空格
(([A-Z]('[A-Z]|[a-z][A-Z])?[a-z]+[A-Z]?|&)\s)+
与以前相同。
\[\d{4}\]\s
这将匹配[
,然后是4个数字,然后是]
[A-Z]+\s\d+
这最后一部分是4个大写字母,然后是数字。我不确定字母和数字是否在某种程度上受到限制,如果大写字母总是4个字母,数字是3到4位数,你可以这样做
[A-Z]{4}\s\d{3,4}
答案 2 :(得分:0)
此正则表达式与两个示例匹配:
([A-Z][A-Za-z\s]+|\s&\s).*(\sv\s)[^\[]*\[[0-9]{4}\]\s[A-Z]+\s[0-9]+
但如果它对另一个人不起作用,请告诉我我将尝试调整答案的文字。
答案 3 :(得分:0)
我不会尝试将字符串与单个正则表达式匹配。请考虑以下事项。
<强>代码强>
R1 = /
\s+v\s+ # match 'v' preceded by >= 1 spaces and followed by >= 1 spaces
| # or
\s+\[ # match a left bracket preceded by >=1 spaces
| # or
\]\s+ # match a right bracket followed by >=1 spaces
/x # free-spacing regex definition mode
def legal_case_name?(str)
party1, party2, year, id = str.split R1
valid_party?(party1) && valid_party?(party2) && valid_year?(year) && valid_id?(id)
end
def valid_party?(party)
return false if party.nil?
party.split.all? { |word| word == '&' || word =~ /\A[[:alpha:]]+\z/ }
end
def valid_year?(year)
return false unless year =~ /\A\d{4}\z/
(1950..2040).cover? year.to_i
end
R2 = /
EWHC\s+\d{4} # match 'EWHC' followed by >= 1 spaces and then 4 digits
| # or
PNLR\s+\d{3} # match 'PNLR' followed by >= 1 spaces and then 3 digits
| # or
ABC\s+\d{5} # match 'ABC' followed by >= 1 spaces and then 5 digits
/x # free-spacing regex definition mode
def valid_id?(id)
(id =~ R2) ? true : false
end
可能需要修改其中一些方法以反映要求。
<强>实施例强>
legal_case_name? "Seele GmbH & Co v Tokyo Insurance Ltd [2009] EWHC 2066"
#=> true
legal_case_name? "Darlington Soc v Scourfield & McCarthy [1999] PNLR 365"
#=> true
legal_case_name? "Darlington Soc vs Scourfield & McCarthy [1999] PNLR 365"
#=> false
legal_case_name? "Darlington Soc v Scourfield & McCarthy [1921] PNLR 365"
#=> false
legal_case_name? "Darlington Soc v Scourfield & McCarthy [1921] PNLR 3652"
#=> false
<强>解释强>
假设
str = "Seele GmbH & Co v Tokyo Insurance Ltd [2009] EWHC 2066"
然后
party1, party2, year, id = str.split R1
#=> ["Seele GmbH & Co", "Tokyo Insurance Ltd", "2009", "EWHC 2066"]
party1
#=> "Seele GmbH & Co"
party2
#=> "Tokyo Insurance Ltd"
year
#=> "2009"
id
#=> "EWHC 2066"
valid_party?(party1)
#=> true
valid_party?(party2)
#=> true
valid_year?(year)
#=> true
valid_id?(id)
#=> true