如何选择将逗号和空格添加到捕获组?

时间:2017-07-30 11:11:24

标签: php regex optional substring capture-group

我试图在每个文本块中匹配五个子串(总共有100个块)。

我匹配99%的文本块,但有关于第3组和第4组的一些错误。

以下是演示链接:{{3}}

第3组是“词性”,第4组是英文翻译。

在第一个文本块中,det, pro应该都在第3组中,然后the; him, her, it, them应该在第4组中。

在第三个文本块中再次出现同样的问题 第3组应为adj, det, nm, pro,第4组应为a, an, one

这是我的模式:

([0-9]+)\s+(\w+(?:, \w+)?)\s+(\N+?)\s+(\H.+).*?\r?\n•\s+([\s\S]*?)\s+[0-9]+\s\|.*\s*

2 个答案:

答案 0 :(得分:1)

... Voici

/^(\d+) +(\w+) +([acdefijlmnoprtv()]+(?:, ?[acdefijlmnoprtv()]+)*) +([\S\s]+?)\n\x{2022} +([\S\s]+?)\n\d+ \| [-\dn]+\s*/gum

Demo Link

我已尽力优化模式。我的模式减少了近10,000步,并根据需要达到了100场比赛。

  • 起始锚^用于识别每个区块的开始(效率/准确度)
  • \d代替[0-9](简洁)
  • \s将替换为适用的文字空间(简洁性)
  • 使用特定字母和括号的字符类代替捕获组3的\w。(效率)*可以用[\w()]替换为简洁而效率低下
  • 使用文字\x{2022}(个人偏好)
  • 指定了项目符号
  • 用于每个块[-\dn]的尾随字符的字符类。 (效率/准确度)

答案 1 :(得分:1)

当您必须描述包含许多部分的长字符串时,第一个反射是使用自由空间模式(x修饰符)和命名组(即使命​​名组在替换上下文中不是很有用,它们也有帮助使模式可读并且更容易调试):

~^
(?<No> [0-9]+ )  \h+
(?<word> \pL+ )  \h+
(?<type> [\pL()]+ (?: , \h* [\pL()]+ )* )  \h+
(?<wd_tr> [^•]* [^•\s] )  \h* \R

• \h*
(?<sent_fr> [^–]* [^\s–] )   \s* – \s*
(?<sent_eng> .* (?:\R .*)*? )  \h* \R

(?<num1> [0-9]+ )  \h* \| \h*
(?<num2> .*\S )
~xum

demo

没有神奇的方法可以为格式模糊的字符串构建模式。您所能做的就是在开始时最紧缩,并在遇到不匹配的情况时增加灵活性。