在PHP中,我将http://pastebin.com/PfjEgQpd中的文字与以下正则表达式匹配:
preg_match('#(.*(?s))(particella |particelle |p\.|part\.|p |part |mappale |mapp\.|mapp |n\.|\*) *(\d+[\d /\p{Pd}]*)($|.{0,20}(?s)(graffati|particella |particelle |p\.|.*part\.|p |part |mappale |mapp\.|mapp |n\.|subalterno |subalterni |sub\.|s\.|sub |s |\bcat\b|\bcategoria\b|\brendita\b|\bvani\b|\bconsistenza\b|\bR\.C\.\b))#i', $txt, $matches, PREG_OFFSET_CAPTURE, $offset)
$offset = 944
,我在$matches
中获得以下输出。
我希望与1184
匹配,但它与4
相匹配。
我也试过(?sU)
而没有运气。
$matches = array(6) {
[0]=>
array(2) {
[0]=>
string(59) "* 1184 sub.702, vioolo San Vincenzo n.4, piano T, Categoria"
[1]=>
int(1226)
}
[1]=>
array(2) {
[0]=>
string(36) "* 1184 sub.702, vioolo San Vincenzo "
[1]=>
int(1226)
}
[2]=>
array(2) {
[0]=>
string(2) "n."
[1]=>
int(1262)
}
[3]=>
array(2) {
[0]=>
string(1) "4"
[1]=>
int(1264)
}
[4]=>
array(2) {
[0]=>
string(20) ", piano T, Categoria"
[1]=>
int(1265)
}
[5]=>
array(2) {
[0]=>
string(9) "Categoria"
[1]=>
int(1276)
}
}
$offset = int(944)
答案 0 :(得分:0)
将我的评论转化为答案:重点是模式中有贪婪的子模式:.*
和{0,20}
。它们应该变成 lazy 子模式,否则,你捕获的文本只会包含1个符号(左贪婪的子模式"狼吞虎咽"尽可能多,并且不会让小组旁边的它捕获超过1个符号,因为它们至少需要一个符号)。
请参阅IDEONE demo,使用
$re = '~(.*?(?s))(particella |particelle |p\.|part\.|p |part |mappale |mapp\.|mapp |n\.|\*) *(\d+[\d /\p{Pd}]*)($|.{0,20}?(?s)(graffati|particella |particelle |p\\.|.*part\\.|p |part |mappale |mapp\.|mapp |n\.|subalterno |subalterni |sub\.|s\.|sub |s |\bcat\b|\bcategoria\b|\brendita\b|\bvani\b|\bconsistenza\b|\bR\.C\.\b))~';
由于您的模式过于脆弱,我对其进行了优化并将
替换为\s
,因为您的意图是匹配这些地方的所有空格:
(?s)(.*?)(particell[ea]\s+|p(?:art)?[.\s]+|mapp(?:(?:ale)?\s+|\.)|n\.|\*)\s*(\d+[\d\s/\p{Pd}]*)($|.{0,20}?(graffati|particell[ae]\s+|p(?:art)?[.\s]+|mapp(?:(?:ale)?\s+|\.)|n\.|subaltern[oi]\s+|s(?:ub)?[.\s]+|\bcat(?:egoria)?\b|\brendita\b|\bvani\b|\bconsistenza\b|\bR\.C\.\b))