stringx

package module
v0.0.0-...-06157fb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 1, 2023 License: BSD-2-Clause, MIT Imports: 9 Imported by: 1

README

stdx/stringx: Extended String Library

This library contains extended functionality for strings (and slices thereof) that could prove useful, including many that are common in other languages.

Like the standard library, we assume all strings are UTF-8 encoded.

This package uses Huan Du's xstrings library for much of the functionality, but this module tries to be compatible with the Ruby language where possible, and thus many functions have been extended, (e.g. with default parameters or modes of operation).

Some functionality is also pulled from Mawuli Kofi Adzoe's stringutil package and modified for this library.

Where a function can be found in other languages' standard libraries, I try to stay close to the Ruby syntax and features, as I am most familiar with that language and the features of its standard library are quite robust.

Functions

CaseCmp

Compares self and other string, ignoring case, and returns -1 if other string is larger, 0 if the two are equal, or -1 if other string is smaller.

CaseCmp("foo", "foo")        // 0
CaseCmp("foo", "food")       // -1
CaseCmp("food", "foo")       // 1
CaseCmp("FOO", "foo")        // 0
CaseCmp("foo", "FOO")        // 0
Center

Centers str in width. If width is greater than the length of str, returns a new string of length width with str centered and padded with pad; otherwise, returns str.

Center("hello", 4)            // "hello"
Center("hello", 20)           // "       hello        "
Center("hello", 20, "123")    // "1231231hello12312312"
Chomp

Returns a new String with the given record separator removed from the end of str (if present). If using the default separator, then chomp also removes carriage return characters (that is it will remove \n, \r, and \r\n). If $/ is an empty string, it will remove all trailing newlines from the string.

Chomp("hello")               // "hello"
Chomp("hello\n")             // "hello"
Chomp("hello\r\n")           // "hello"
Chomp("hello\n\r")           // "hello\n"
Chomp("hello\r")             // "hello"
Chomp("hello \n there")      // "hello \n there"
Chomp("hello", "llo")        // "he"
Chomp("hello\r\n\r\n", "")   // "hello"
Chomp("hello\r\n\r\r\n", "") // "hello\r\n\r"
Chop

Chop returns a new String with the last character removed. If the string ends with \r\n, both characters are removed. Applying Chop to an empty string returns an empty string.

Chop("string\r\n")        // "string"
Chop("string\n\r")        // "string\n"
Chop("string\n")          // "string"
Chop("string")            // "strin"
Chop(Chop("x"))           // ""
Chr

Chr returns a string containing the first rune of str.

Chr("foo")    // "f"
Count

Each other_str parameter defines a set of characters to count. The intersection of these sets defines the characters to count in str. Any other_str that starts with a caret (^) is negated. The sequence c1-c2 means all characters between c1 and c2. The backslash character ("") can be used to escape ^ or - and is otherwise ignored unless it appears at the end of a sequence or the end of a other_str.

Not Implemented Because: The version in xtrings has a different algorithm for its pattern. It is just as valid a function, but I'm trying to stick with Ruby algorithms here. The version in stdlib doesn't support patterns at all.

str := "hello world"
Count(str, "lo")                 // 5
Count(str, "lo", "o")            // 2
Count(str, "hello", "^l")        // 4
Count("hello", "ej-m")           // 4

str = "hello^world"
Count(str, "\\^aeiou")           // 4
Count(str, "a\\-eo")             // 3

str = "hello world\\r\\n"
Count(str, "\\")                 // 2
Count(str, "\\A")                // 0
Count(str, "A-\\w")              // 3
Delete

Returns a copy of str with all characters in the intersection of its arguments deleted. Uses the same rules for building the set of characters as Count().

Delete("hello", "l", "lo")            // "yelow mon"
Delete("hello", "lo")                 // "he"
Delete("hello", "aeiou", "^e")        // "hell"
Delete("hello", "ej-m")               // "ho"
DeleteMatchingRunes

DeleteMatchingRunes deletes all instances of the rune r from the given string str.

DeleteMatchingRunes("hello", 'l')        // "heo"
DeleteRune

DeleteRune deletes a single rune from string str at the given index.

DeleteRune("hello", 3)        // "helo"

Note that this may not always correspond to the actual byte index as UTF-8 runes may span multiple bytes.

FormatStrings

FormatStrings takes a []string and returns a string similar to that returned by fmt.Println([]string{...}), but with each element quoted for readability.

slice := []string{"one", "two", "three", "four "}

// Normal Output
fmt.PrintLn(slice)                   // [one two three four ]

// With FormatStrings:
fmt.Println(FormatStrings(slice))    // ["one", "two", "three", "four "]
Gsub

Gsub Returns a copy of str with all occurrences of pattern substituted for the second argument. The pattern is typically a Regexp; if given as a String, any regular expression metacharacters it contains will be interpreted literally, e.g. \d will match a backslash followed by 'd', instead of a digit.

If replacement is a string it will be substituted for the matched text. It may contain back-references to the pattern's capture groups of the form \d, where d is a group number. Unlike in Ruby, \k is unsupported.

GSub("hello", regexp.MustCompile(`[aeiou]`), "*")                 // "h*ll*"
GSub("hello", regexp.MustCompile(`([aeiou])`), "<\1>")            // "h<e>ll<o>"
GSub("hello", regexp.MustCompile(`.`), func(s string) string {    // "104 101 108 108 111 "
	return strconv.Itoa(Ord(s)) + " "
})
Index

Returns the integer index of the first match for the given argument, or -1 if none found; the search of str is forward, and begins at position offset (in runes).

When sub is a string, returns the index of the first matching substring in str:

Index("foo", "f")        // 0
Index("foo", "o")        // 1
Index("foo", "oo")       // 1
Index("foo", "ooo")      // -1
Index("recr", "c")       // 2
Index("こんにちは", "ち") // 3

When sub is a *regexp.Regexp, returns the index of the first match str:

Index("foo", regexp.MustCompile(`o.`))         // 1
Index("foo", regexp.MustCompile(`.o`))         // 0

With positive integer offset, begins the search at position offset:

Index("foo", "o", 1)        // 1
Index("foo", "o", 2)        // 2
Index("foo", "o", 3)        // -1
Index("recr", "c", 1)       // 2
Index("こんにちは", "ち", 2) // 3

With negative integer offset, selects the search position by counting backward from the end of str:

Index("foo", "o", -1)        // 2
Index("foo", "o", -2)        // 1
Index("foo", "o", -3)        // 1
Index("foo", "o", -4)        // -1
Index("foo", regexp.MustCompile(`o.`), -2) // 1
Index("foo", regexp.MustCompile(`.o`), -2) // 1
Insert

Insert Inserts the given other string into str; returns the new string.

If the Integer index is positive or zero, inserts other at offset index:

Insert("foo", 1, "bar")            // "fbaroo"

If the Integer index is negative, counts backward from the end of str and inserts other at offset index + 1 (that is, after str[index]):

Insert("foo", -2, "bar")           // "fobaro"

Insert does no utf-8 validation of the other string.

InsertRune

InsertRune inserts rune r into s at position p. No checking is done to validate r is a valid utf-8 rune.

If p is greater than len(s) - 1, it is set to len(p) - 1.

str := "helloworld"
InsertRune(str, ' ', 5)                 // "hello world"
InsertRune(str, '!', 10)                // "helloworld!"
InsertRunes

InsertRunes is like InsertRune, but you can pass multiple runes and they will all be inserted at the given position p.

If p is greater than len(s) - 1, it is set to len(p) - 1.

str := "helloworld"
InsertRunes(str, 5, ',', ' ')                 // "hello, world"
IsASCII

IsASCII returns true if s consists entirely of ASCII characters. Pulled straight from stdlib and exported.

Ord

Ord returns the Integer ordinal of a one-character string.

Partition

Partition Searches sep or pattern (regexp) in the string and returns the part before it, the match, and the part after it. If it is not found, returns two empty strings and str.

Partition("hello", "l")                      // []string{"he", "l", "lo"}
Partition("hello", "x")                      // []string{"hello", "", ""}
Partition("hello", regexp.MustCompile(`.l`)) // []string{"h", "el", "lo"}
Reverse

Reverse returns a new string with the characters from str in reverse order.

Reverse("stressed")        // "desserts"
Rindex

Returns the Integer index of the last occurrence of the given substring, or -1 if none found:

Rindex("foo", "f")        // 0
Rindex("foo", "o")        // 2
Rindex("foo", "oo")       // 1
Rindex("foo", "ooo")      // -1

Returns the Integer index of the last match for the given *Regexp or -1 if none found:

Rindex("foo", regexp.MustCompile(`f`))        // 0
Rindex("foo", regexp.MustCompile(`o`))        // 2
Rindex("foo", regexp.MustCompile(`oo`))       // 1
Rindex("foo", regexp.MustCompile(`ooo`))      // -1

Integer argument offset, if given and non-negative, specifies the maximum starting position in the string to end the search:

Rindex("foo", "o", 0)        // -1
Rindex("foo", "o", 1)        // 1
Rindex("foo", "o", 2)        // 2
Rindex("foo", "o", 3)        // 2

If offset is a negative Integer, the maximum starting position in the string to end the search is the sum of the string's length and offset:

Rindex("foo", "o", -1)        // 2
Rindex("foo", "o", -2)        // 1
Rindex("foo", "o", -3)        // -1
Rindex("foo", "o", -4)        // -1

If str or sub is empty or nil, or if sub is not a string or *regexp.Regexp, Rindex will return -1.

Scan

Both forms iterate through str, matching the pattern (which may be a *Regexp or a string). For each match, a result is generated and either added to the result array or passed to the function. If the pattern contains no groups, each individual result consists of the matched string. If the pattern contains groups, each individual result is itself a slice containing one entry per group.

a := "cruel world"
Scan(a, regexp.MustCompile(`\w+`))        // ["cruel", "world"]
Scan(a, regexp.MustCompile(`...`))        // ["cru", "el ", "wor"]
Scan(a, regexp.MustCompile(`(...)`))      // [["cru"], ["el "], ["wor"]]
Scan(a, regexp.MustCompile(`(..)(..)`))   // [["cr", "ue"], ["l ", "wo"]]

And when given a function:

Scan(a, regexp.MustCompile(`\w+`), func(match interface{}){
	...
	fmt.Printf("<<%s>> \n", match)
})

produces:

<<cruel>> <<world>>
Scrub

If the string contains any invalid byte sequences then replace invalid bytes with given replacement string, else returns str. If repl is given as a function, replace invalid bytes with returned value of the function.

str := "ab\uFFFDcd\xFF\xCEefg\xFF\xFC\xFD\xFAhijk"
Scrub(str)                        // "ab\uFFFDcd\uFFFDefg\uFFFDhijk"
Scrub(str, "")                    // "abcdefghijk"
Scrub(str, ".")                   // "ab.cd.efg.hijk"

Scrub(str, func(r rune) string {  // "ab!cd!efg!hijk"
	return "!"
})
Split

Split divides s into substrings based on a pattern, returning a slice of these substrings.

If pattern is a string, then its contents are used as the delimiter when splitting s. If pattern is a single space, s is split on whitespace, with leading and trailing whitespace and runs of contiguous whitespace characters ignored.

If pattern is a Regexp, s is divided where the pattern matches. Whenever the pattern matches a zero-length string, s is split into individual characters. If pattern contains groups, the respective matches will be returned in the slice as well.

If pattern is nil, s is split on whitespace as if " " had been passed as the pattern.

If the limit parameter is omitted, trailing null fields are suppressed. If limit is a positive number, at most that number of split substrings will be returned (captured groups will be returned as well, but are not counted towards the limit). If limit is 1, the entire string is returned as the only entry in a slice. If negative, there is no limit to the number of fields returned, and trailing null fields are not suppressed.

When the input s is empty an empty slice is returned as the string is considered to have no fields to split.

Split(" now's  the time ")                 // []string{"now's", "the", "time"}
Split(" now's  the time ", ' ')            // []string{"now's", "the", "time"}

re := regexp.MustCompile(` `)
Split(" now's  the time", re)              // []string{"", "now's", "", "the", "time"}

re = regexp.MustCompile(`,\s*`)
Split("1, 2.34,56, 7", re)                 // []string{"1", "2.34", "56", "7"}

re = regexp.MustCompile(``)
Split("hello", re)                         // []string{"h", "e", "l", "l", "o"}
Split("hello", re, 3)                      // []string{"h", "e", "llo"}

re = regexp.MustCompile(`\s*`)
Split("hi mom", re))                       // []string{"h", "i", "m", "o", "m"}

Split("mellow yellow", "ello")             // []string{"m", "w y", "w"}
Split("1,2,,3,4,,", ",")                   // []string{"1", "2", "", "3", "4"}
Split("1,2,,3,4,,", ",", 4)                // []string{"1", "2", "", "3,4,,"}
Split("1,2,,3,4,,", ",", -4)               // []string{"1", "2", "", "3", "4", "", ""}

re = regexp.MustCompile(`(:)()()`)
Split("1:2:3", re, 2)                      // []string{"1", ":", "", "", "2:3"}

Split("", ",", -1)                         // []string{}
Squeeze

Squeeze builds a set of characters from the other string parameter(s) using the procedure described for Count(). Returns a new string where runs of the same character that occur in this set are replaced by a single character. If no arguments are given, all runs of identical characters are replaced by a single character.

Squeeze("yellow moon", "")             // "yelow mon"
Squeeze("  now   is  the", "m-z")      // " now is the"
Squeeze("putters shoot balls", " ")    // "puters shot balls"
Tr

Returns a copy of str with the characters in from_str replaced by the corresponding characters in to_str. If to_str is shorter than from_str, it is padded with its last character in order to maintain the correspondence.

Tr("hello", "el", "ip")        // "hippo"
Tr("hello", "aeiou", "*")      // "h*ll*"
Tr("hello", "aeiou", "AA*")    // "hAll*"

Both strings may use the c1-c2 notation to denote ranges of characters, and from_str may start with a ^, which denotes all characters except those listed.

Tr("hello", "a-y", "b-z")     // "ifmmp"
Tr("hello", "^aeiou", "*")    // "*e**o"

The backslash character \ can be used to escape ^ or - and is otherwise ignored unless it appears at the end of a range or the end of the from_str or to_str:

Tr("hello^world", "\\^aeiou", "*") // "h*ll**w*rld"
Tr("hello-world", "a\\-eo", "*")   // "h*ll**w*rld"

Tr("hello\r\nworld", "\r", "")     // "hello\nworld"
Tr("hello\r\nworld", "\\r", "")    // "hello\r\nwold"
Tr("hello\r\nworld", "\\\r", "")   // "hello\nworld"

Tr("X['\\b']", "X\\", "")          // "['b']"
Tr("X['\\b']", "X-\\]", "")        // "'b'"
Truncate

Truncate truncates a given str after a given length if str is longer than length:

Truncate("Once upon a time in a world far far away", 27)             // "Once upon a time in a wo..."

Pass a string or *Regexp separator to truncate str at a natural break:

Truncate("Once upon a time in a world far far away", 27, "...", " ") // "Once upon a time in a..."
Truncate("Once upon a time in a world far far away", 27, "...", regexp.MustCompile(`\s`))
  // "Once upon a time in a..."

The last characters will be replaced with the :omission string (defaults to "...") for a total length not exceeding length:

Truncate("And they found that many people were sleeping better.", 25, "... (continued)")
  // "And they f... (continued)"

License

This package is licensed under MIT.

However, the code does use two external libraries:

  • Huan Du's xstrings library is used for some functionality, and it is also licensed under MIT. Please see the LICENSE file for details.
  • Mawuli Kofi Adzoe's stringutil package is used for some functionality, and it is licensed under a BSD 2-clause license. See the LICENSE file for details.

TODO & Contributing

Here are some things that could be done to improve the library:

  • Get more functions, particularly those in the wish list ported.
  • Additional useful functions that aren't in other languages?
  • Clean up the test suite
  • More tests are always good
  • Optimizations (maybe?)

I make no claims of being an expert at optimization, and there may well be evidence herein. If you find something that can be done better, a case where a function fails where it shouldn't, or any other issue, feel free to submit an issue (a PR is even better!) once I open up the issues tracker.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CaseCmp

func CaseCmp(str, other string) int

Compares self and other string, ignoring case, and returns -1 if other string is larger, 0 if the two are equal, or - 1 if other string is smaller.

CaseCmp("foo", "foo")        // 0
CaseCmp("foo", "food")       // -1
CaseCmp("food", "foo")       // 1
CaseCmp("FOO", "foo")        // 0
CaseCmp("foo", "FOO")        // 0

func Center

func Center(s string, width int, pad ...string) string

Centers str in width. If width is greater than the length of str, returns a new String of length width with str centered and padded with pad; otherwise, returns str.

Center("hello", 4)            // "hello"
Center("hello", 20)           // "       hello        "
Center("hello", 20, "123")    // "1231231hello12312312"

func Chomp

func Chomp(str string, separator ...string) string

Returns a new String with the given record separator removed from the end of str (if present). If using the default separator, then chomp also removes carriage return characters (that is it will remove \n, \r, and \r\n). If $/ is an empty string, it will remove all trailing newlines from the string.

Chomp("hello")               // "hello"
Chomp("hello\n")             // "hello"
Chomp("hello\r\n")           // "hello"
Chomp("hello\n\r")           // "hello\n"
Chomp("hello\r")             // "hello"
Chomp("hello \n there")      // "hello \n there"
Chomp("hello", "llo")        // "he"
Chomp("hello\r\n\r\n", "")   // "hello"
Chomp("hello\r\n\r\r\n", "") // "hello\r\n\r"`

func Chop

func Chop(str string) string

Chop returns a new String with the last character removed. If the string ends with \r\n, both characters are removed. Applying chop to an empty string returns an empty string.

Chop("string\r\n")        // "string"
Chop("string\n\r")        // "string\n"
Chop("string\n")          // "string"
Chop("string")            // "strin"
Chop(Chop("x"))           // ""

func Chr

func Chr(str string) string

Chr returns a string containing the first rune of str.

Chr("foo")    // "f"

func Count

func Count(str string, other_str ...string) int

Each other_str parameter defines a set of characters to count. The intersection of these sets defines the characters to count in str. Any other_str that starts with a caret ^ is negated. The sequence c1-c2 means all characters between c1 and c2. The backslash character \ can be used to escape ^ or - and is otherwise ignored unless it appears at the end of a sequence or the end of a other_str.

str := "hello world"
Count(str, "lo")                 // 5
Count(str, "lo", "o")            // 2
Count(str, "hello", "^l")        // 4
Count("hello", "ej-m")           // 4

str = "hello^world"
Count(str, "\\^aeiou")           // 4
Count(str, "a\\-eo")             // 3

str = "hello world\\r\\n"
Count(str, "\\")                 // 2
Count(str, "\\A")                // 0
Count(str, "A-\\w")              // 3

func Delete

func Delete(s string, pattern ...string) string

Returns a copy of str with all characters in the intersection of its arguments deleted. Uses the same rules for building the set of characters as String#count.

Delete("hello", "l", "lo")            // "yelow mon"
Delete("hello", "lo")                 // "he"
Delete("hello", "aeiou", "^e")        // "hell"
Delete("hello", "ej-m")               // "ho"

func DeleteMatchingRunes

func DeleteMatchingRunes(str string, r rune) string

DeleteMatchingRunes deletes all instances of the rune r from the given string str.

DeleteMatchingRunes("hello", 'l')        // "heo"

func DeleteRune

func DeleteRune(str string, index int) string

DeleteRune deletes a single rune from string str at the given index.

DeleteRune("hello", 3)        // "helo"

Note that this may not always correspond to the actual byte index as UTF-8 runes may span multiple bytes.

func EachRune

func EachRune(str string, block func(r rune))

Passes each character in str to the given function

func FormatStrings

func FormatStrings(arr []string) string

FormatStrings takes a []string and returns a string similar to that returned by fmt.Println([]string{...}), but with each element quoted for readability.

func Gsub

func Gsub(orig string, match, replacer interface{}) string

Gsub Returns a copy of str with all occurrences of pattern substituted for the second argument. The pattern is typically a Regexp; if given as a String, any regular expression metacharacters it contains will be interpreted literally, e.g. \d will match a backslash followed by 'd', instead of a digit.

If replacement is a String it will be substituted for the matched text. It may contain back-references to the pattern's capture groups of the form \d, where d is a group number. Unlike in Ruby, \k is unsupported.

GSub("hello", regexp.MustCompile(`[aeiou]`), "*")                 // "h*ll*"
GSub("hello", regexp.MustCompile(`([aeiou])`), "<\1>")            // "h<e>ll<o>"
GSub("hello", regexp.MustCompile(`.`), func(s string) string {    // "104 101 108 108 111 "
	return strconv.Itoa(Ord(s)) + " "
})

func Index

func Index(str string, sub interface{}, offset ...int) int

Returns the integer index of the first match for the given argument, or -1 if none found; the search of str is forward, and begins at position offset (in runes).

When sub is a string, returns the index of the first matching substring in str:

Index("foo", "f")        // 0
Index("foo", "o")        // 1
Index("foo", "oo")       // 1
Index("foo", "ooo")      // -1
Index("recr", "c")       // 2
Index("こんにちは", "ち") // 3

When sub is a *regexp.Regexp, returns the index of the first match str:

Index("foo", regexp.MustCompile(`o.`))         // 1
Index("foo", regexp.MustCompile(`.o`))         // 0

With positive integer offset, begins the search at position offset:

Index("foo", "o", 1)        // 1
Index("foo", "o", 2)        // 2
Index("foo", "o", 3)        // -1
Index("recr", "c", 1)       // 2
Index("こんにちは", "ち", 2) // 3

With negative integer offset, selects the search position by counting backward from the end of str:

Index("foo", "o", -1)        // 2
Index("foo", "o", -2)        // 1
Index("foo", "o", -3)        // 1
Index("foo", "o", -4)        // -1
Index("foo", regexp.MustCompile(`o.`), -2) // 1
Index("foo", regexp.MustCompile(`.o`), -2) // 1

func Insert

func Insert(str string, index int, other string) string

Insert Inserts the given other string into str; returns the new string.

If the Integer index is positive or zero, inserts other at offset index:

Insert("foo", 1, "bar")            // "fbaroo"

If the Integer index is negative, counts backward from the end of str and inserts other string at offset index+1 (that is, after str[index]):

Insert("foo", -2, "bar")           // "fobaro"

Insert does no utf-8 validation of the other string.

func InsertRune

func InsertRune(s string, r rune, p int) string

InsertRune inserts rune r into s at position p. No checking is done to validate r is a valid utf-8 rune.

If p is greater than len(s)-1, it is set to len(p)-1.

str := "helloworld"
InsertRune(str, ' ', 5)                 // "hello world"
InsertRune(str, '!', 10)                // "helloworld!"

func InsertRunes

func InsertRunes(s string, p int, rs ...rune) string

InsertRunes is like InsertRune, but you can pass multiple runes and they will all be inserted at the given position p.

If p is greater than len(s)-1, it is set to len(p)-1.

str := "helloworld"
InsertRunes(str, 5, ',', ' ')                 // "hello, world"

func IsASCII

func IsASCII(s string) bool

IsASCII returns true if s consists entirely of ASCII characters. Pulled straight from stdlib and exported.

func MatchingStringsets

func MatchingStringsets(a, b interface{}) bool

MatchingStringsets returns true if the two []string or [][]string slices are equal otherwise returns false.

func Ord

func Ord(str string) int

Ord returns the Integer ordinal of a one-character string.

func Partition

func Partition(str string, pat interface{}) []string

Partition Searches sep or pattern (regexp) in the string and returns the part before it, the match, and the part after it. If it is not found, returns str and two empty strings.

Partition("hello", "l")                      // []string{"he", "l", "lo"}
Partition("hello", "x")                      // []string{"hello", "", ""}
Partition("hello", regexp.MustCompile(`.l`)) // []string{"h", "el", "lo"}

func Reverse

func Reverse(str string) string

Reverse returns a new string with the characters from str in reverse order.

Reverse("stressed")        // "desserts"

func Rindex

func Rindex(str string, sub interface{}, offset ...int) int

Returns the Integer index of the last occurrence of the given substring, or -1 if none found:

Rindex("foo", "f")        // 0
Rindex("foo", "o")        // 2
Rindex("foo", "oo")       // 1
Rindex("foo", "ooo")      // -1

Returns the Integer index of the last match for the given *Regexp or -1 if none found:

Rindex("foo", regexp.MustCompile(`f`))        // 0
Rindex("foo", regexp.MustCompile(`o`))        // 2
Rindex("foo", regexp.MustCompile(`oo`))       // 1
Rindex("foo", regexp.MustCompile(`ooo`))      // -1

Integer argument offset, if given and non-negative, specifies the maximum starting position in the string to _end_ the search:

Rindex("foo", "o", 0)        // -1
Rindex("foo", "o", 1)        // 1
Rindex("foo", "o", 2)        // 2
Rindex("foo", "o", 3)        // 2

If offset is a negative Integer, the maximum starting position in the string to end the search is the sum of the string's length and offset:

Rindex("foo", "o", -1)        // 2
Rindex("foo", "o", -2)        // 1
Rindex("foo", "o", -3)        // -1
Rindex("foo", "o", -4)        // -1

If str or sub is empty or nil, or if sub is not a string or *regexp.Regexp, Rindex will return -1.

func RuneIndexFromStartByte

func RuneIndexFromStartByte(str string, index int) int

RuneIndexFromStartByte returns the index of the rune that starts at the byte index index, or -1 if index is not a rune boundary.

func RuneIndicies

func RuneIndicies(str string) map[int]int

RuneIndicies returns the starting byte indicies of all runes in str as a map[int]int, or nil if str is empty.

func Scan

func Scan(str string, pattern interface{}, block ...func(match interface{})) interface{}

Both forms iterate through str, matching the pattern (which may be a *Regexp or a string). For each match, a result is generated and either added to the result array or passed to the function. If the pattern contains no groups, each individual result consists of the matched string. If the pattern contains groups, each individual result is itself a slice containing one entry per group.

a := "cruel world"
Scan(a, regexp.MustCompile(`\w+`))        // ["cruel", "world"]
Scan(a, regexp.MustCompile(`...`))        // ["cru", "el ", "wor"]
Scan(a, regexp.MustCompile(`(...)`))      // [["cru"], ["el "], ["wor"]]
Scan(a, regexp.MustCompile(`(..)(..)`))   // [["cr", "ue"], ["l ", "wo"]]

And when given a function:

Scan(a, regexp.MustCompile(`\w+`), func(match interface{}){
	...
	fmt.Printf("<<%s>> \n", match)
})

produces:

<<cruel>> <<world>>

func Scrub

func Scrub(str string, repl ...interface{}) string

If the string contains any invalid byte sequences then replace invalid bytes with given replacement string, else returns str. If repl is given as a function, replace invalid bytes with returned value of the function.

str := "ab\uFFFDcd\xFF\xCEefg\xFF\xFC\xFD\xFAhijk"
Scrub(str)                        // "ab\uFFFDcd\uFFFDefg\uFFFDhijk"
Scrub(str, "")                    // "abcdefghijk"
Scrub(str, ".")                   // "ab.cd.efg.hijk"

Scrub(str, func(r rune) string {  // "ab!cd!efg!hijk"
	return "!"
})

func Split

func Split(s string, pattern interface{}, limit ...int) []string

Split divides s into substrings based on a pattern, returning a slice these substrings.

If pattern is a string, then its contents are used as the delimiter when splitting str. If pattern is a single space, str is split on whitespace, with leading and trailing whitespace and runs of contiguous whitespace characters ignored.

If pattern is a Regexp, str is divided where the pattern matches. Whenever the pattern matches a zero-length string, str is split into individual characters. If pattern contains groups, the respective matches will be returned in the array as well.

If pattern is nil, s is split on whitespace as if " " had been passed as the pattern.

If the limit parameter is omitted, trailing null fields are suppressed. If limit is a positive number, at most that number of split substrings will be returned (captured groups will be returned as well, but are not counted towards the limit). If limit is 1, the entire string is returned as the only entry in an array. If negative, there is no limit to the number of fields returned, and trailing null fields are not suppressed.

When the input str is empty an empty Array is returned as the string is considered to have no fields to split.

Split(" now's  the time ")                 // []string{"now's", "the", "time"}
Split(" now's  the time ", ' ')            // []string{"now's", "the", "time"}

re := regexp.MustCompile(` `)
Split(" now's  the time", re)              // []string{"", "now's", "", "the", "time"}

re = regexp.MustCompile(`,\s*`)
Split("1, 2.34,56, 7", re)                 // []string{"1", "2.34", "56", "7"}

re = regexp.MustCompile(``)
Split("hello", re)                         // []string{"h", "e", "l", "l", "o"}
Split("hello", re, 3)                      // []string{"h", "e", "llo"}

re = regexp.MustCompile(`\s*`)
Split("hi mom", re))                       // []string{"h", "i", "m", "o", "m"}

Split("mellow yellow", "ello")             // []string{"m", "w y", "w"}
Split("1,2,,3,4,,", ",")                   // []string{"1", "2", "", "3", "4"}
Split("1,2,,3,4,,", ",", 4)                // []string{"1", "2", "", "3,4,,"}
Split("1,2,,3,4,,", ",", -4)               // []string{"1", "2", "", "3", "4", "", ""}

re = regexp.MustCompile(`(:)()()`)
Split("1:2:3", re, 2)                      // []string{"1", ":", "", "", "2:3"}

Split("", ",", -1)                         // []string{}

Currently does not support the block version.

func Squeeze

func Squeeze(s string, other ...string) string

Squeeze builds a set of characters from the other_str parameter(s) using the procedure described for String#count. Returns a new string where runs of the same character that occur in this set are replaced by a single character. If no arguments are given, all runs of identical characters are replaced by a single character.

Squeeze("yellow moon", "")             // "yelow mon"
Squeeze("  now   is  the", "m-z")      // " now is the"
Squeeze("putters shoot balls", " ")    // "puters shot balls"

func Tr

func Tr(str, from, to string) string

Returns a copy of str with the characters in from_str replaced by the corresponding characters in to_str. If to_str is shorter than from_str, it is padded with its last character in order to maintain the correspondence.

Tr("hello", "el", "ip")        // "hippo"
Tr("hello", "aeiou", "*")      // "h*ll*"
Tr("hello", "aeiou", "AA*")    // "hAll*"

Both strings may use the c1-c2 notation to denote ranges of characters, and from_str may start with a ^, which denotes all characters except those listed.

Tr("hello", "a-y", "b-z")     // "ifmmp"
Tr("hello", "^aeiou", "*")    // "*e**o"

The backslash character \ can be used to escape ^ or - and is otherwise ignored unless it appears at the end of a range or the end of the from_str or to_str:

Tr("hello^world", "\\^aeiou", "*") // "h*ll**w*rld"
Tr("hello-world", "a\\-eo", "*")   // "h*ll**w*rld"

Tr("hello\r\nworld", "\r", "")     // "hello\nworld"
Tr("hello\r\nworld", "\\r", "")    // "hello\r\nwold"
Tr("hello\r\nworld", "\\\r", "")   // "hello\nworld"

Tr("X['\\b']", "X\\", "")          // "['b']"
Tr("X['\\b']", "X-\\]", "")        // "'b'"

func Truncate

func Truncate(str string, length int, options ...interface{}) string

Truncate truncates a given str after a given length if str is longer than length:

Truncate("Once upon a time in a world far far away", 27)             // "Once upon a time in a wo..."

Pass a string or *Regexp separator to truncate str at a natural break:

Truncate("Once upon a time in a world far far away", 27, "...", " ") // "Once upon a time in a..."

Truncate("Once upon a time in a world far far away", 27, "...", regexp.MustCompile(`\s`))
  // "Once upon a time in a..."

The last characters will be replaced with the :omission string (defaults to "...") for a total length not exceeding length:

Truncate("And they found that many people were sleeping better.", 25, "... (continued)")
  // "And they f... (continued)"

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL