【问题标题】:How can I grab a specified number of words with special characters in them with RegExp?如何使用 RegExp 获取指定数量的带有特殊字符的单词?
【发布时间】:2014-09-21 21:55:23
【问题描述】:

我目前正在使用 Ruby 中的 Markov chain text generator 应用程序,该应用程序接收文本主体(“语料库”),然后根据该文本生成新文本。我目前需要解决的问题是编写一个正则表达式,它将返回包含我指定的单词数的数组。我在这里要做的就是抓取一定数量的单词(由用户指定),但在整个字符串中多次。

离开我见过的另一个应用程序,我正在使用/(([.,?"();\-!':—^\w]+ ){#{depth}})/ 之类的东西,其中#{depth} 一次插入多少个单词。这应该一次抓取两个单词,同时允许一部分特殊字符,这就是让我感兴趣的部分。所以总的问题是:如何动态指定我想要的单词数(由空格分隔),同时还允许这些单词中包含一系列特殊字符?

这是我目前拥有的:

# Regex
@match_regex = /(([.,?"();\-!':—^\w]+ ){2})/
s = input.scan(@match_regex).to_a
puts s.inspect

# Input
Within weeks they planned a meeting. She sent him poetry along with her itinerary,
having worked in a business meeting to excuse the opportunity. He prepared flowers
and a banner of welcome on his hearth. 

# Output - seems to be grabbing last word again for some reason
[["Within weeks ", "weeks "], ["they planned ", "planned "], ["a meeting. ", "meeting. "],
["She sent ", "sent "], ["him poetry ", "poetry "], ["along with ", "with "],
["her itinerary, ", "itinerary, "], ["having worked ", "worked "], ["in a ", "a "],
["business meeting ", "meeting "], ["to excuse ", "excuse "],
["the opportunity. ", "opportunity. "], ["He prepared ", "prepared "], ["flowers and ", "and "],
["a banner ", "banner "], ["of welcome ", "welcome "], ["on his ", "his "]]

# Desired output. I'm not picky if it has trailing spaces or not as I can always trim that
["Within weeks", "they planned", "a meeting.", "She sent", "him poetry", "along with",
"her itinerary," "having worked", "in a", "business meeting", "to excuse", "the opportunity.",
"He prepared", "flowers and", "a banner", "of welcome", "on his"]

任何帮助将不胜感激。谢谢!

【问题讨论】:

    标签: ruby regex markov-chains


    【解决方案1】:

    在正则表达式中,每组括号都会创建一个捕获组,对于输入中找到的每个匹配项,Ruby 都会返回这些组的列表。

    您有两组括号:第一组围绕整个表达式,第二组围绕每个单词(请注意,对于重复捕获组(例如 (foo){x} ),仅返回最后一个实例)。因此,每场比赛都有两个项目列表。

    要获得所需的内容,您需要删除这些捕获组。第一组可以简单地删除,第二组你想让它成为非捕获组,要做到这一点,你用?:开始你的括号。 因此,您想要的表达式是:

    @match_regex = /(?:[.,?"();\-!':—^\w]+ ){2}/

    【讨论】:

      【解决方案2】:

      如果我正确理解了您的问题,我认为这应该适合您:

      def split_it(text, num_words, special_chars)
        text.scan(/(?:[\w#{special_chars}]+(?:\s+|$)){#{num_words}}/)
      end
      
      text =<<_
      Within weeks they planned a meeting. She sent him poetry along with her itinerary,
      having worked in a business meeting to excuse the opportunity. He prepared flowers
      and a banner of welcome on his hearth.
      _
      
      special_chars = ".,?\"();\\-!':"
      
      split_it(text, 2, special_chars)
        #=> ["Within weeks ", "they planned ", "a meeting. ", "She sent ", "him poetry ",
        #    "along with ", "her itinerary,\n", "having worked ", "in a ",
        #    "business meeting ", "to excuse ", "the opportunity. ", "He prepared ",
        #    "flowers\nand ", "a banner ", "of welcome ", "on his "]
      split_it(text, 3, special_chars)
        #=> ["Within weeks they ", "planned a meeting. ", "She sent him ",
        #    "poetry along with ", "her itinerary,\nhaving ", "worked in a ",
        #    "business meeting to ", "excuse the opportunity. ", "He prepared flowers\n",
        #    "and a banner ", "of welcome on "]
      

      special_chars 中注明\\-。如果您有-\-,它将出现在正则表达式的括号之间,为-,Ruby 会认为您定义了一个范围,并会引发异常。额外的反斜杠导致\- 出现在括号之间,告诉Ruby 它是文字-。 @Amadan 指出如果- 位于字符串的开头或结尾,则不需要擒纵。

      马尔可夫链?嗯。

      【讨论】:

      • 处理- 的另一种策略是确保它是括号中的第一个或最后一个字符;这样,即使没有转义,它也将表示文字破折号而不是范围。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-30
      • 2020-06-06
      • 2022-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      相关资源
      最近更新 更多