2017-06-03 123 views
-5

我有一些字符串与一个句子,我需要将它细分为最多40个字符的子字符串。 但我不想在一个词的中间分割这个句子。Ruby:将字符串拆分为最多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

尝试'句子[/ \ A. {0,40} \ b/m]' –

+1

你有句子的例子,输出应该是什么? –

+0

@WiktorStribiżew它仅返回第一个事件。 – Blueone

回答

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)和多行匹配。

一个很轻微的注意的是,因为这正则表达式是匹配 40个字符(而不是零),就可以得到一个空的结果。 (虽然这看起来不太可能,因为你需要1个字,41个字母的字符串!!)为了说明这个边缘情况,如果需要,请致电.to_s


更新:谢谢你的改进编辑你的问题,提供输入/结果的具体例子。这使得你所要求的更清晰,因为原来的帖子有些模棱两可。

你可以用类似下面的解决这个问题:

sentence.scan(/.{0,39}[a-z.!?,;](?:\b|$)/mi) 
  • String#scan返回该模式匹配的字符串阵列 - 这样你就可以重新加入这些字符串来重构原始。
  • 再次,我添加了几个字符(!?,;)到“子字符串中的最后字符”列表中。随意根据需要调整它。
  • (?:\b|$)的意思是“字边界,或行末”。这解决了在子字符串中不包括最终.的结果问题。请注意,我使用了非捕获组(?:)以防止scan的结果发生变化。
+0

非常感谢您的帮助,但这只是第一次发生。我的例子是“当然,只有当我们知道东门已经打开时,我们才会展示自己。”我想要这个字符串输出:[“当然,我们只会显示自己,当我们”,“知道东门被打开了。”] – Blueone

+0

汤姆,它几乎工作,但我没有在数组输出中的最后一个字符。我的意思是点。这可能是。 | ! | ?你有好主意吗 ?谢谢。享受你的一天;-) – Blueone

+0

嗨@Blueone,我已经更新了我的回答,现在我回到了键盘。 –

相关问题