Home > Blockchain >  In Scala, how to get the ANSI display length of a String?
In Scala, how to get the ANSI display length of a String?

Time:09-03

This is an minimalistic example:

  it("actual length") {

    import scala.io.AnsiColor
    val str = AnsiColor.RED   "c"   AnsiColor.RESET

    assert(str.length == 1)
  }

But when this test is executed, it shows that the length of the str is 10, while the display length of it should be 1 (all ANSI escape characters should have 0 length)

How to correct it?

CodePudding user response:

The length method's doc says this actually counts the number of Unicode code units:

In the Java SE API documentation, Unicode code point is used for character values in the range between U 0000 and U 10FFFF, and Unicode code unit is used for 16-bit char values that are code units of the UTF-16 encoding.

   /**
     * Returns the length of this string.
     * The length is equal to the number of Unicode code units in the string.
     *
     * Returns the length of the sequence of characters represented by this object.
     */
    public int length() {
        return value.length >> coder();
    }

There is not built-in solution to count what you want, but you can simply remove them using a regex. AnsiColor escape codes seems to have a precise pattern: \u001b [ 1-2 digits m

  val str: String = AnsiColor.RED   "c"   AnsiColor.RESET
  println(str.replaceAll("\\u001B\\[\\d{1,2}m", "").length) // 1

CodePudding user response:

The length method's doc says this actually counts the number of Unicode code units:

In the Java SE API documentation, Unicode code point is used for character values in the range between U 0000 and U 10FFFF, and Unicode code unit is used for 16-bit char values that are code units of the UTF-16 encoding.

   /**
     * Returns the length of this string.
     * The length is equal to the number of Unicode code units in the string.
     *
     * Returns the length of the sequence of characters represented by this object.
     */
    public int length() {
        return value.length >> coder();
    }

There is not built-in solution to count what you want, but you can simply remove them using a regex. AnsiColor escape codes seems to have a precise pattern: \u001b [ 1-2 digits m

  val str: String = AnsiColor.RED   "c"   AnsiColor.RESET
  println(str.replaceAll("\\u001B\\[\\d*m", "").length) // 1
  • Related