TLDR:
我假设空格是由某些自动化软件插入的,并且单词周围只能有单个空格。
s = "l' avant ou l 'apres ou encore ' maintenant' ou bien 'ceci ' et ' encore de l ' huile ' d 'accord d' accord d ' accord Je n' en ai pas .... s ' entendre Je m'appelle Victor"
first_rx = /(?<=\b[b-df-hj-np-tv-z]) ' ?(?=\p{L})|(?<=\b[b-df-hj-np-tv-z]) ?' (?=\p{L})/i
# If you find it overmatches, replace [b-df-hj-np-tv-z] with [dlnsmtc],
# i.e. first letters of word that are usually contracted
second_rx = /\b'\b\K|' *((?:\b'\b|[^'])+)(?<=\S) *'/
puts s.gsub(first_rx, "'")
.gsub(second_rx) { $~[1] ? "'#{$~[1]}'" : "" }
输出:
l'avant ou l'apres ou encore 'maintenant' ou bien 'ceci' et 'encore de l'huile' d'accord d'accord d'accord Je n'en ai pas .... s'entendre Je m'appelle Victor
说明
这个问题真的很复杂。有几个单词可以缩写并与法语中的撇号一起使用,de、le/la、ne、se、me、te、ce 仅举几例,但这些都是辅音。您可以使用
删除单个独立辅音、撇号和下一个单词之间的所有空格
s.gsub(/(?<=\b[b-df-hj-np-tv-z]) ' ?(?=\p{L})|(?<=\b[b-df-hj-np-tv-z]) ?' (?=\p{L})/i, "'")
如果您发现它过度匹配,请将 [b-df-hj-np-tv-z] 替换为 [dlnsmtc],即通常缩写的单词的第一个字母。请参阅regex demo。
下一步是删除首字母之后和尾随撇号之前的空格。这很棘手:
s.gsub(/\b'\b\K|' *((?:\b'\b|[^'])+)(?<=\S) *'/) { $~[1] ? "'#{$~[1]}'" : "" }
其中\b'\b 旨在匹配单词字符之间的所有撇号,我们在上一步中修复的那些。见this regex demo。由于 Onigmo 正则表达式中没有 (*SKIP)(*F) 支持,正则表达式有点简化,但替换是有条件的:如果组 1 匹配,则替换为 ' + 组 1 值 ($1) + ',否则,替换为空字符串(因为\K 重置匹配,从匹配内存缓冲区中删除所有文本)。
注意:这种方法也可以扩展到处理一些特定情况,例如aujourd'hui。