我有一个方法可以检测不可打印的字符串中的索引,如下所示。
def isPrintable(v:Char) = v >= 0x20 && v <= 0x7E
val ba = List[Byte](33,33,0,0,0)
ba.zipWithIndex.filter { v => !isPrintable(v._1.toChar) } map {v => v._2}
> res115: List[Int] = List(2, 3, 4)
结果列表的第一个元素是索引,但我想知道是否有更简单的方法来执行此操作。
答案 0 :(得分:3)
仅获取满足给定条件的第一个索引:
ba.indexWhere(v => !isPrintable(v.toChar))
(如果没有找到,则返回-1)
答案 1 :(得分:3)
如果你想要第一个不可打印字符的Option[Int]
(如果存在),你可以这样做:
ba.zipWithIndex.collectFirst{
case (char, index) if (!isPrintable(char.toChar)) => index
}
> res4: Option[Int] = Some(2)
如果你想要你的例子中的所有索引,只需使用collect
而不是collectFirst
,你就会得到List
。
答案 2 :(得分:0)
如果只需要第一次出现不可打印的字符
应用于span
的方法List
提供了两个子列表,第一个所有元素都包含条件,第二个以伪造条件的元素开头。在这种情况下考虑,
val (l,r) = ba.span(b => isPrintable(b.toChar))
l: List(33, 33)
r: List(0, 0, 0)
获取第一个不可打印的char的索引,
l.size
res: Int = 2
如果需要,可以出现所有不可打印的字符
考虑给定partition
的{{1}}作为标准。例如,
List
其中val ba2 = List[Byte](33,33,0,33,33)
val (l,r) = ba2.zipWithIndex.partition(b => isPrintable(b._1.toChar))
l: List((33,0), (33,1), (33,3), (33,4))
r: List((0,2))
包含具有不可打印字符的元组及其在原始r
中的位置。
答案 3 :(得分:0)
我不确定是否需要索引或元组列表,我不确定是否&#39; ba&#39;需要是一个字节列表或以字符串开头。
for { i <- 0 until ba.length if !isPrintable(ba(i).toChar) } yield i
这里,因为人们需要表现:)
def getNonPrintable(ba:List[Byte]):List[Int] = {
import scala.collection.mutable.ListBuffer
var buffer = ListBuffer[Int]()
@tailrec
def go(xs: List[Byte], cur: Int): ListBuffer[Int] = {
xs match {
case Nil => buffer
case y :: ys => {
if (!isPrintable(y.toChar)) buffer += cur
go(ys, cur + 1)
}
}
}
go(ba, 0)
buffer.toList
}
答案 4 :(得分:0)
您可以直接使用regexp通过unicode代码点找到不可打印的字符。
资源:Regexp page
通过这种方式,您可以使用这种模式直接过滤字符串,例如:
val text = "this is \n sparta\t\r\n!!!"
text.zipWithIndex.filter(_._1.matches("\\p{C}")).map(_._2)
> res3: Vector(8, 16, 17, 18)
结果你将获得带有String中所有不可打印字符的索引的Vector。看看