我要提取与模式不匹配的一部分字符串
我的模式匹配条件是字符串长度应为5,并且只能包含N或Y。
例如:
NYYYY => valid
NY => Invalid , length is invalid
NYYSY => Invalid. character at position 3 is invalid
如果字符串无效,那么我想找出哪个特定字符不匹配。例如:在NYYSY,第4个字符不匹配。
我尝试在Scala中进行模式匹配
val Pattern = "([NY]{5})".r
paramList match {
case Pattern(c) => true
case _ => false
}
答案 0 :(得分:2)
返回表明验证状态的String
。
def validate(str :String, len :Int, cs :Seq[Char]) :String = {
val checkC = cs.toSet
val errs = str.zipAll(Range(0,len), 1.toChar, -1).flatMap{ case (c,x) =>
if (x < 0) Some("too long")
else if (checkC(c)) None
else if (c == 1) Some("too short")
else Some(s"'$c' at index $x")
}
str + ": " + (if (errs.isEmpty) "valid" else errs.distinct.mkString(", "))
}
测试:
validate("NTYYYNN", 4, "NY") //res0: String = NTYYYNN: 'T' at index 1, too long
validate("NYC", 7, "NY") //res1: String = NYC: 'C' at index 2, too short
validate("YNYNY", 5, "NY") //res2: String = YNYNY: valid
答案 1 :(得分:1)
这是一种返回(Char, Int)
个无效字符元组及其在给定字符串中的对应位置的列表的方法:
def checkString(validChars: List[Char], validLength: Int, s: String) = {
val Pattern = s"([${validChars.mkString}]{$validLength})".r
s match {
case Pattern(_) => Vector.empty[(Char, Int)]
case s =>
val invalidList = s.zipWithIndex.filter{case (c, _) => !validChars.contains(c)}
if (invalidList.nonEmpty) invalidList else Vector(('\u0000', -1))
}
}
List("NYYYY", "NY", "NNSYYTN").map(checkString(List('N', 'Y'), 5, _))
// res1: List(Vector(), Vector((?,-1)), Vector((S,2), (T,5)))
如上所示,empty
列表表示有效字符串,而(null-char, -1)
列表表示字符串具有有效字符但长度无效。
答案 2 :(得分:0)
以下是一条可能适合您需求的建议:
"NYYSY".split("(?<=[^NY])|(?=[^NY])").foreach(println)
NYY
S
Y
当前一个字符或后一个字符不是Y
或N
时,此解决方案会在任意点分割输入字符串。这会将有效和无效字符的每个岛作为单独的行放置在输出中。
答案 3 :(得分:0)
您可以使用其他正则表达式来检测特定问题:
val Pattern = "([NY]{5})".r
val TooLong = "([NY]{5})(.+)".r
val WrongChar = "([NY]*)([^NY].*)".r
paramList match {
case Pattern(c) => // Good
case TooLong(head, rest) => // Extra character(s) in sequence
case WrongChar(head, rest) => // Wrong character in sequence
case _ => // Too short
}
您可以使用head.length
来计算错误的索引,而失败的字符是rest.head
。
答案 4 :(得分:0)
您可以通过模式匹配字符串的每个字符来实现,而无需使用任何形式的正则表达式或复杂的字符串操作。
def check(value: String): Unit = {
if(value.length!=5) println(s"$value length is invalid.")
else value.foldLeft((0, Seq[String]())){
case (r, char) =>
char match {
case 'Y' | 'N' => r._1+1 -> r._2
case c @ _ => r._1+1 -> {r._2 ++ List(s"Invalid character `$c` in position ${r._1}")}
}
}._2 match {
case Nil => println(s"$value is valid.")
case errors: List[String] => println(s"$value is invalid - [${errors.mkString(", ")}]")
}
}
check("NYCNBNY")
NYNYNCC length is invalid.
check("NYCNB")
NYCNB is invalid - [Invalid character `C` in position 2, Invalid character `B` in position 4]
check("NYNNY")
NYNNY is valid.