我有一些带句子的字符串,我需要将其细分为最多40个字符的子字符串。 但是我不想把句子分成一个单词。
我尝试使用.gsub函数,但它最多返回40个字符并避免在单词中间剪切字符串。但它只是第一次出现。
sentence[0..40].gsub(/\s\w+$/,'')
我试过分裂,但我只能选择前40个字符,并在一个单词的中间分开......
sentence.split(...){40}
我的字符串是"Sure, we will show ourselves only when we know the east door has been opened."
。
我想要的字符串输出是
["Sure, we will show ourselves only when we","know the east door has
been opened."]
你有解决方案吗?谢谢
答案 0 :(得分:2)
您的第一次尝试:
sentence[0..40].gsub(/\s\w+$/,'')
几乎有效,但它有一个致命的缺陷。您正在分割之前>>切断最后一个单词的字符数。这意味着你无法知道被删除的位是一个完整的单词还是一个部分单词。
因此,您的代码将始终切断最后一个单词。
我会按如下方式解决问题:
sentence[/\A.{0,39}[a-z]\b/mi]
\A
是将正则表达式修复为字符串开头的锚点。.{0,39}[a-z]
匹配1到40个字符,其中最后一个字符必须是字母。这是为了防止最后选择的字符成为标点符号或空格。 (这是期望的行为吗?您的问题没有真正指定。如果需要,请随意调整/移除[a-z]
部分,例如[a-z.]
以匹配句点。)\b
是一个单词边界环视。它是一个零宽度的匹配器,在单词的开头/结尾。/mi
修饰符将包含不区分大小写(即A-Z
)和多行匹配。一个非常小的注意事项是,因为这个正则表达式匹配 1 到40个字符(而不是零),所以可以获得null结果。 (虽然这似乎不太可能,因为你需要一个单字,41 +字母字符串!)为了解释这个边缘情况,如果需要,请在结果上调用.to_s
。
更新:感谢您对问题的改进编辑,提供输入/结果的具体示例。这使得你要求的内容更加清晰,因为原帖有些含糊不清。
您可以使用以下内容解决此问题:
sentence.scan(/.{0,39}[a-z.!?,;](?:\b|$)/mi)
String#scan
返回与模式匹配的字符串的数组 - 因此您可以重新连接这些字符串以重建原始字符串。!?,;
)。随意根据需要调整它。(?:\b|$)
表示“字边界,或行尾”。这解决了结果的问题,不包括子串中的最终.
。请注意,我使用了非捕获组(?:
)来阻止scan
的结果发生变化。