Search

Dark theme | Light theme
Showing posts with label GroovyGoodness:String. Show all posts
Showing posts with label GroovyGoodness:String. Show all posts

September 9, 2025

Groovy Goodness: Get Next And Previous Characters

Since Groovy 1.8.2 the next and previous methods are added to the Character class. When you invoke the method next on a char or Character instance the next character is returned. And when you use the previous method the previous character is returned.
Groovy 5 adds an overloaded version of the next and previous method that accepts an int argument. With this argument you can specify the number of characters to skip before returning the next or previous character. For example 'a'.next(2) return 'c' and 'c'.previous(2) returns 'a'.

March 11, 2020

Groovy Goodness: Getting Parts Of A String Enclosed By Strings

Groovy 3 adds the takeBetween method to the String class. With this method we can get all the characters that are enclosed by string values. We can specify one enclosed string value and then all text between the the first occurrence of the string and the second occurrence is returned. If multiple parts are enclosed by the string values we can also specify which occurrence we want. If the text is enclosed by different string values we can use a variant of takeBetween that takes two string values to indicate the boundaries of the text we want. Also with two different enclosed string values we can use an argument to get the n-th occurrence of the string that is found.
Since Groovy 3 we can also use takeBefore and takeAfter to get the string before or after a given string value. All three methods will return an empty string if no text can be found.

In the following example we use the takeBefore, takeAfter and takeBetween methods with different arguments:

def text = 'Just saying: "Groovy is gr8!"'

// Return all characters before the first quote.
assert text.takeBefore('"') == 'Just saying: '
// Return everything after the colon.
assert text.takeAfter(': ') == '"Groovy is gr8!"'
// Return everything between two quotes.
assert text.takeBetween('"') == 'Groovy is gr8!'
// Return text between is and !.
assert text.takeBetween('is', '!') == ' gr8'

// When no value can be found
// an empty string is returned.
assert text.takeBefore('?') == ''
assert text.takeAfter('Java') == ''
assert text.takeBetween('-') == ''
assert text.takeBetween('[', '/') == ''

def sample = 'JVM languages are "Groovy", "Clojure", "Java".'

assert sample.takeBetween('"') == 'Groovy'
// We can also specify which occurrence we 
// want for a text between same strings.
assert sample.takeBetween('"', 0) == 'Groovy'
assert sample.takeBetween('"', 1) == 'Clojure'
assert sample.takeBetween('"', 2) == 'Java'


def users = "Users: [mrhaki], [hubert]"

assert users.takeBetween('[', ']') == 'mrhaki'
// We can also specify which occurrence we 
// want for a text between to strings.
assert users.takeBetween('[', ']', 0) == 'mrhaki'
assert users.takeBetween('[', ']', 1) == 'hubert'
// When no occurrence an empty string is returned.
assert users.takeBetween('[', ']', 2) == ''

Written with Groovy 3.0.2.

March 10, 2020

Groovy Goodness: Taking Or Dropping Number Of Characters From A String

Groovy adds a lot of methods to the Java String class. For example we can use the take method to get a certain number of characters from the start of a string value. With the drop method we remove a given number of characters from the start of the string. In Groovy 3 we can now also take and drop a certain number of characters from the end of a string using the methods takeRight and dropRight.

In the following example we see how we can use the methods:

def s = "Groovy rocks!"

// Drop first 7 characters.
assert s.drop(7) == "rocks!"

// Drop last 7 characters.
assert s.dropRight(7) == "Groovy"


// Take first 6 characters.
assert s.take(6) == "Groovy"

// Take last 6 characters.
assert s.takeRight(6) == "rocks!"

Written with Groovy 3.0.2.

June 12, 2018

Groovy Goodness: Calculate MD5 And SHA Hash Values

Groovy adds a lot of useful methods to the String class. Since Groovy 2.5.0 we can even calculate MD5 and SHA hash values using the methods md5 and digest. The md5 method create a hash value using the MD5 algorithm. The digest method accepts the name of the algorithm as value. These values are dependent on the available algorithms on our Java platform. For example the algorithms MD2, MD5, SHA-1, SHA-256, SHA-384 and SHA-512 are by default available.

In the next example we use the md5 and digest methods on a String value:

def value = 'IamASecret'

def md5 = value.md5()

// We can provide hash algorithm with digest method.
def md2 = value.digest('MD2')
def sha1 = value.digest('SHA-1')
def sha256 = value.digest('SHA-256')

assert md5 == 'a5f3147c32785421718513f38a20ca44'
assert md2 == '832cbe3966e186194b1203c00ef47488'
assert sha1 == '52ebfed118e0a411e9d9cbd60636fc9dea718928'
assert sha256 == '4f5e3d486d1fd6c822a81aa0b93d884a2a44daf2eb69ac779a91bc76de512cbe'

Written with Groovy 2.5.0.

June 11, 2018

Groovy Goodness: Base64 URL and Filename Safe Encoding

Groovy supported Base64 encoding for a long time. Since Groovy 2.5.0 we can also use Base64 URL and Filename Safe encoding to encode a byte array with the method encodeBase64Url. The result is a Writable object. We can invoke the toString method on the Writable object to get a String value. An encoded String value can be decoded using the same encoding with the method decodeBase64Url that is added to the String class.

In the following example Groovy code we encode and decode a byte array:

import static java.nio.charset.StandardCharsets.UTF_8 

def message = 'Groovy rocks!'

// Get bytes array for String using UTF8.
def messageBytes = message.getBytes(UTF_8)

// Encode using Base64 URL and Filename encoding.
def messageBase64Url = messageBytes.encodeBase64Url().toString()

// Encode using Base64 URL and Filename encoding with padding.
def messageBase64UrlPad = messageBytes.encodeBase64Url(true).toString()

assert messageBase64Url == 'R3Jvb3Z5IHJvY2tzIQ'
assert messageBase64UrlPad == 'R3Jvb3Z5IHJvY2tzIQ=='

// Decode the String values.
assert new String(messageBase64Url.decodeBase64Url()) == 'Groovy rocks!'
assert new String(messageBase64UrlPad.decodeBase64Url()) == 'Groovy rocks!'

Written with Groovy 2.5.0.

June 22, 2016

Groovy Goodness: Turn A Map Or List As String To Map Or List

In a previous post we learned how to use the toListString or toMapString methods. With these methods we create a String representation of a List or Map object. With a bit of Groovy code we can take such a String object and turn it into a List or Map again.

In the following code snippet we turn the String value [abc, 123, Groovy rocks!] to a List with three items:

// Original List with three items.
def original = ['abc', 123, 'Groovy rocks!']

// Create a String representation:
// [abc, 123, Groovy rocks!]
def listAsString = original.toListString()

// Take the String value between
// the [ and ] brackets, then
// split on , to create a List
// with values.
def list = listAsString[1..-2].split(', ')

assert list.size() == 3
assert list[0] == 'abc'
assert list[1] == '123' // String value
assert list[2] == 'Groovy rocks!'

We can do something similar for a String value representing a map structure:

// Original Map structure.
def original = [name: 'mrhaki', age: 42]

// Turn map into String representation:
// [name:mrhaki, age:42]
def mapAsString = original.toMapString()

def map = 
    // Take the String value between
    // the [ and ] brackets.
    mapAsString[1..-2]
        // Split on , to get a List.
        .split(', ')
        // Each list item is transformed
        // to a Map entry with key/value.
        .collectEntries { entry -> 
            def pair = entry.split(':')
            [(pair.first()): pair.last()]
        }
        

assert map.size() == 2
assert map.name == 'mrhaki'
assert map.age == '42'

Written with Groovy 2.4.7.

April 4, 2014

Groovy Goodness: GString as Writable

The Groovy API has the interface Writable. Classes that implement this interface are capable of writing their selves to a java.io.Writer object. The interface has one method writeTo() where the code is that writes the contents to a given Writer instance. Most implementations will also use the implementation of the writeTo() method in their toString() implementation.

The GString implementation in Groovy also implements the Writable interface. This means we can redirect the GString contents to some Writer instance if we want to. In the following code we use a FileWriter to write the contents of a GString to a file:

def data = [
    new Expando(id: 1, user: 'mrhaki', country: 'The Netherlands'),
    new Expando(id: 2, user: 'hubert', country: 'The Netherlands'),
]

data.each { userData ->
    new File("${userData.id}.txt").withWriter('UTF-8') { fileWriter ->
        // Use writeTo method on GString to save
        // result in a file.
        "User $userData.user lives in $userData.country".writeTo(fileWriter)
    }
}


assert new File('1.txt').text == 'User mrhaki lives in The Netherlands'
assert new File('2.txt').text == 'User hubert lives in The Netherlands'

Code written with Groovy 2.2.2

November 18, 2013

Groovy Goodness: Remove Part of String With Regular Expression Pattern

Since Groovy 2.2 we can subtract a part of a String value using a regular expression pattern. The first match found is replaced with an empty String. In the following sample code we see how the first match of the pattern is removed from the String:

// Define regex pattern to find words starting with gr (case-insensitive).
def wordStartsWithGr = ~/(?i)\s+Gr\w+/

assert ('Hello Groovy world!' - wordStartsWithGr) == 'Hello world!'
assert ('Hi Grails users' - wordStartsWithGr) == 'Hi users'


// Remove first match of a word with 5 characters.
assert ('Remove first match of 5 letter word' - ~/\b\w{5}\b/) == 'Remove  match of 5 letter word'


// Remove first found numbers followed by a whitespace character.
assert ('Line contains 20 characters' - ~/\d+\s+/) == 'Line contains characters'

Code written with Groovy 2.2.

September 9, 2013

Groovy Goodness: Check if a String Only Contains Whitespaces

In Groovy we can check if a String value only contains whitespaces with the isAllWhitespace() method. The method checks for spaces, but also takes into account tab and newline characters as whitespace.

assert ''.allWhitespace
assert '  '.allWhitespace
assert '\t '.allWhitespace
assert ' \r\n '.allWhitespace

assert !'mrhaki'.allWhitespace

September 6, 2013

Groovy Goodness: Replace Characters in a String with CollectReplacements

We can use the collectReplacements(Closure) method to replace characters in a String. We pass a closure to the method and the closure is invoked for each character in the String value. If we return null the character is not transformed, otherwise we can return the replacement character.

def s = 'Gr00vy is gr8'

def replacement = {
    // Change 8 to eat
    if (it == '8') {
        'eat'
    // Change 0 to o
    } else if (it == '0') {
        'o'
    // Do not transform
    } else {
        null
    }
}

assert s.collectReplacements(replacement) == 'Groovy is great'

Code written with Groovy 2.1.6

October 2, 2012

Groovy Goodness: Drop or Take Elements with Condition

In Groovy we can use the drop() and take() methods to get elements from a collection or String object. Since Groovy 1.8.7 we also can use the dropWhile() and takeWhile() methods and use a closure to define a condition to stop dropping or taking elements. With the dropWhile() method we drop elements or characters until the condition in the closure is true. And the takeWhile() method returns elements from a collection or characters from a String until the condition of the closure is true.

In the following example we see how we can use the methods:

def s = "Groovy Rocks!"

assert s.takeWhile { it != 'R' } == 'Groovy '
assert s.dropWhile { it != 'R' } == 'Rocks!'


def list = 0..10

assert 0..4 == list.takeWhile { it < 5 }
assert 5..10 == list.dropWhile { it < 5 }


def m = [name: 'mrhaki', loves: 'Groovy', worksAt: 'JDriven']

assert [name: 'mrhaki'] == m.takeWhile { key, value -> key.length() == 4 }
assert [loves: 'Groovy', worksAt: 'JDriven'] == m.dropWhile { it.key == 'name' }

(Code is written with Groovy 2.0.4)

April 27, 2011

Groovy Goodness: New Dollar Slashy Strings

Groovy already has a lot of ways to define a String value, and with Groovy 1.8 we have another one: the dollar slashy String. This is closely related to the slashy String definition we already knew (which also can be multi-line by the way, added in Groovy 1.8), but with different escaping rules. We don't have to escape a slash if we use the dollar slashy String format, which we would have to do otherwise.

def source = 'Read more about "Groovy" at http://mrhaki.blogspot.com/'

// 'Normal' slashy String, we need to escape / with \/
def regexp = /.*"(.*)".*\/(.*)\//  

def matcher = source =~ regexp
assert matcher[0][1] == 'Groovy'
assert matcher[0][2] == 'mrhaki.blogspot.com'

// Dollar slash String.
def regexpDollar = $/.*"(.*)".*/(.*)//$  

def matcherDollar = source =~ regexpDollar
assert matcherDollar[0][1] == 'Groovy'
assert matcherDollar[0][2] == 'mrhaki.blogspot.com'

def multiline = $/
Also multilines 
are supported.
/$

Groovy Goodness: Get Unique Characters in a String

Groovy adds the toSet() method to the String class in version 1.8. With this method we get a Set of unique String values from the original String value.

String s = 'Groovy is gr8!'

assert s.toSet().sort().join() == ' !8Ggiorsvy'

December 16, 2010

Groovy Goodness: Transform String into Enum

After reading Groovy, State of the Union - Groovy Grails eXchange 2010 by Guillaume Laforge I discovered that in Groovy 1.7.6 we can transform a String into a Enum value. We can use type coersion or the as keyword to turn a String or GString into a corresponding Enum value (if possible).

enum Compass {
    NORTH, EAST, SOUTH, WEST
}

// Coersion with as keyword.
def north = 'NORTH' as Compass
assert north == Compass.NORTH

// Coersion by type.
Compass south = 'south'.toUpperCase()
assert south == Compass.SOUTH

def result = ['EA', 'WE'].collect {
    // Coersion of GString to Enum.
    "${it}ST" as Compass
}
assert result[0] == Compass.EAST
assert result[1] == Compass.WEST

November 29, 2010

Groovy Goodness: String Continuation

Groovy makes writing concise code easy,. We can use the continuation character (\) in a String to split up the definition over multiple lines.

def name ='mrhaki'

def s = "This is not a multiline\
 String, $name, but the continuation\
 character (\\) makes it more readable."
        
assert 'This is not a multiline String, mrhaki, but the continuation character (\\) makes it more readable.' == s

July 14, 2010

Groovy Goodness: Get to Know More About a GString

One of Groovy's great features is the GString. With the GString we can write strings containing expressions that are evaluated. We create a GString if our string is inside double quotes. We can found out information about the expressions in our GString with some simple methods and properties:


def user = 'mrhaki'
def language = 'Groovy'

def s = "Hello ${user}, welcome to ${language}."

assert 2 == s.valueCount
assert ['mrhaki', 'Groovy'] == s.values
assert 'mrhaki' == s.getValue(0)
assert 'Groovy' == s.getValue(1)
assert 32 == s.length()
assert 'Hello ' == s.strings[0]
assert ', welcome to ' == s.strings[1]
assert '.' == s.strings[2]
assert 'Hello mrhaki, welcome to Groovy.' == s

June 20, 2010

Groovy Goodness: Strip Leading Spaces from Lines with Margin

Since Groovy 1.7.3 we can use the stripMargin() method to strip characters up to and including a margin character from multiline strings. The default character is the pipe symbol (|), but we can pass a parameter to the method and use a custom character.

def s = '''\
        |Groovy
        |Grails
        |Griffon'''
        
assert '''\
Groovy
Grails
Griffon''' == s.stripMargin()

def s1 = '''\
   * Gradle
   * GPars
   * Spock''' 
   
assert '''\
 Gradle
 GPars
 Spock''' == s1.stripMargin("* ")

June 15, 2010

Groovy Goodness: Text Translation

In Groovy 1.7.3 the tr() method is added to the String class. With this method we can do translations in String values. We define a source set of characters that need to be replaced by a replacement set of characters. We can also use a regular expression style (remember it is not a real regular expression) to define a range of characters.

If the replacement set is smaller than the source set, than the last character of the replacement set is used for the remaining source set characters.

// Source set and replacement set are equal size.
assert 'I 10v3 9r00vy' == 'I love Groovy'.tr('loeG', '1039')

// Regular expression style range
assert 'mrHAKI' == 'mrhaki'.tr('a-k', 'A-K')

// Replacement set is smaller than source set.
assert 'Gr8888' == 'Groovy'.tr('ovy', '8')

June 14, 2010

Groovy Goodness: Strip Leading Spaces from Lines

Multiline strings are very useful in Groovy. But sometimes they can mess up our code formatting especially if we want to use the multiline string's value literally. If our lines cannot start with spaces we must define our multiline string that way:

class Simple {

    String multi() {
        '''\
Multiline string
with simple 2 space
indentation.'''
    }

    // Now in Groovy 1.7.3:
    String multi173() {
        '''\
        Multiline string
        with simple 2 space
        indentation.'''.stripIndent()
    }

}

Since Groovy 1.7.3 we can strip leading spaces from such lines, so we can align the definition of our multiline string the way we want with the stripIndent() method. Groovy finds the line with the least spaces to determine how many spaces must be removed from the beginning of the line. Or we can tell the stripIndent() method how many characters must be removed from the beginning of the line.

def multi = '''\
  Multiline string
  with simple 2 space
  indentation.'''

assert '''\
Multiline string
with simple 2 space
indentation.''' == multi.stripIndent()

assert '''\
ine string
imple 2 space
ation.''' == multi.stripIndent(8)  // We can define the number of characters ourselves as well.

Groovy Goodness: Expand or Unexpand Space or Tab Delimited Text

Groovy 1.7.3 adds new functionality to the String class. For example we can use the expand() method to expand tabs in a String to spaces with a default tab stop size of 8. We can use a parameter to use a different tab stop size. But we can also go the other way around.

So if we have a tabular text based on spaces we can convert the String to a tab separated String. Here the default tab stop size is also 8, but we can use the parameter to define a different tab stop size.

// Simple ruler to display 0 up to 30
def ruler = (0..30).inject('\n') { result, c -> 
    result += (c % 10) 
}

def stringWithTabs = 'Groovy\tGrails\tGriffon'

println ruler
println stringWithTabs.expand()  // default tab stop is 8
println stringWithTabs.expand(10)  // tab stop is 10

// Output:
// 0123456789012345678901234567890
// Groovy  Grails  Griffon
/ /Groovy    Grails    Griffon

assert 'Groovy  Grails  Griffon' == stringWithTabs.expand()
assert 'Groovy    Grails    Griffon' == stringWithTabs.expand(10)


def stringWithSpaces = 'Hubert  Klein   Ikkink'
def stringWithSpaces10 = 'Hubert    Klein     Ikkink'
println ruler
println stringWithSpaces
println stringWithSpaces10

// Output:
// 0123456789012345678901234567890
// Hubert  Klein   Ikkink
// Hubert    Klein     Ikkink

assert 'Hubert\tKlein\tIkkink' == stringWithSpaces.unexpand()
assert 'Hubert\tKlein\tIkkink' == stringWithSpaces10.unexpand(10)