【问题标题】:For a given string check if matches the pattern [scala]对于给定的字符串,检查是否匹配模式 [scala]
【发布时间】:2018-03-15 23:49:00
【问题描述】:

我是 Scala 的初学者,我想知道如何构建一个函数来检查它是否与明确的模式匹配?

例如:

def patternFound(s:String): Boolean = (s) match {
    case s matches xyxy pattern => true //where x,y are two consecutive characters in the string
    case s matches xxyy pattern => false //where x, y are two characters in that string
    case (_) => false //default
}
//Here x,y are not definite characters but the string s should match a pattern 
//which consist a string of pattern containing characters in alternating positions

patternFound("babab")//true because pattern of xyxy found in it
patternFound("baabba")//false because pattern of xxyy found in it

谁能举例说明我如何做到这一点?

正在寻找一种解决方案,该解决方案对于字符串中出现的任何 xyxyxy 模式返回 true,但在该字符串中的模式为 xxyy 时返回 false。

示例:如果字符串是“babab”或 “ababa”(其中包含模式 xyxy),但为“aabba”返回 false 或“bbaab”(其中包含模式 xxyy)

感谢任何帮助!提前谢谢你。

【问题讨论】:

    标签: regex scala functional-programming pattern-matching


    【解决方案1】:

    语法不正确。 您需要从函数主体中删除“s 匹配”,它已经在方法定义行“(s)匹配”中。

    另见https://docs.scala-lang.org/tour/pattern-matching.html

    【讨论】:

    • 感谢您的反馈。我知道这一点。这就是为什么我正在寻找我能做些什么来匹配某种模式。在我的示例中,x,y 是未定义的字符。
    【解决方案2】:

    这可能通过正则表达式和环顾四周来实现,但我刚刚创建了一个辅助函数:

    /**
      * Checks for recurring pattern in a String
      * @param s The input String to check
      * @param patternSize The size of the expected pattern.  For example in the String "aabbaabbaabb" the pattern is "aabb" which is a length of 4
      */
    def checkPattern(s: String, patternSize: Int): Boolean = {
      val grouped = s.grouped(patternSize)
      grouped.toSet.size == 1 // everything should be the same
    }
    

    该函数的一些示例用法:

    checkPattern("abababab", 2) // true
    checkPattern("aabbaabbaabb", 2) // false
    checkPattern("aabbaabbaabb", 4) // true
    checkPattern("abcabcabc", 3) // true
    

    因此,对于您的代码,您可以将其与一些保护语句一起使用:

    def patternFound(s: String): Boolean = s match {
      case "" => false // empty Strings can't have patterns
      case s if checkPattern(s, 2) => true
      case s if checkPattern(s, 4) => true
      case _ => false
    }
    
    patternFound("ababababab") // true
    patternFound("aabbaabb") // true
    patternFound("aabbzz") // false
    

    编辑:我认为其他答案更适合您正在寻找的内容,但这是我对您更新问题的更新答案:

    def patternFound(s: String): Boolean = s match {
      s.nonEmpty && checkPattern(s, 2)
    }
    

    【讨论】:

    • 嗨@Tyler 我真的很感激这个解决方案,但它并不是我想要的,尽管它确实足以解决我提出的问题。一旦我有足够的代表这样做,我肯定会支持你的解决方案。但我实际上正在寻找一个解决方案,它对 xyxyxy.... 或 yxyxyx... 的模式返回 true,但对 xxyy.... 或 yyxx.... 的模式返回 true。 /跨度>
    • 您似乎更新了您的问题。我会更新我的答案。
    【解决方案3】:

    对于您发布的两个示例,这两个正则表达式模式将涵盖它。

    def patternFound(s:String): Boolean = {
      val ptrn1 = "(.)(.)\\1\\2".r
      val ptrn2 = "(.)\\1(.)\\2".r
      s match {
        case ptrn1(_,_) => true
        case ptrn2(_,_) => true
        case _ => false
      }
    }
    

    证明:

    patternFound("rrgg")  // res0: Boolean = true
    patternFound("hqhq")  // res1: Boolean = true
    patternFound("cccx")  // res2: Boolean = false
    

    但我怀疑您的要求,如所述,不够具体,无法准确涵盖您正在寻找的内容。


    更新

    你的第二个要求现在没有意义了。 与第一个模式不匹配的所有内容都将返回 false,因此没有必要测试特定模式以返回 false

    def patternFound(s:String): Boolean = {
      val ptrn = "(.)(.)\\1\\2".r.unanchored
      s match {
        case ptrn(_,_) => true
        case _ => false
      }
    }
    patternFound("babab")   //true because pattern of xyxy found in it
    patternFound("baabba")  //false because it doesn't match the target pattern
    

    【讨论】:

    • 老实说,我很惊讶!这真的很强大,很神奇。但是我想要实现的是编写一个函数,它将为字符串“babab”返回true,因为它包含模式xyxy(“babab”的子字符串是匹配重复模式的baba)。如果传递的字符串是“aabba”,则相同的函数应该返回 false,因为其中包含模式 xxyy(“aabba”的子字符串是“aabb”,匹配 xxyy => false)
    • @MoodyCody;请说清楚。您的问题是 matches "xxyy" => true,但现在您说“匹配 xxyy => false”。
    • 我已经相应地更新了这个问题。措辞可能有点误导。我还在问题中包含了示例以阐明要求。
    • 太棒了!像魅力一样工作!如果你不介意我可以问我应该遵循哪本书/参考资料来更好地学习 scala(这样我也可以按照你的方式创建模式匹配)吗?
    • 这个问题更多的是关于正则表达式,而不是关于 Scala。这是两个不同的东西。您可能会花一些时间在Regular-Expressions.info 上,但我相信网上有很多不错的 RE 教程。
    猜你喜欢
    • 2012-09-17
    • 2010-12-19
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 1970-01-01
    • 2014-12-29
    • 1970-01-01
    相关资源
    最近更新 更多