Case insensitive string replace in Go - string

Can NewReplacer.Replace do case insensitive string replacement?
r := strings.NewReplacer("html", "xml")
fmt.Println(r.Replace("This is <b>HTML</b>!"))
If not, what's the best way to do case insensitive string replace in Go?

You can use regular expressions for that:
re := regexp.MustCompile(`(?i)html`)
fmt.Println(re.ReplaceAllString("html HTML Html", "XML"))
Playground: http://play.golang.org/p/H0Gk6pbp2c.
It's worth noting that case is a thing that can be different depending on the language and locale. For example, the capital form of German letter "ß" is "SS". While this doesn't generally influence English texts, this is something to bear in mind when working with multi-lingual texts and programs that need to work them.

A generic solution would be as follows:
import (
"fmt"
"regexp"
)
type CaseInsensitiveReplacer struct {
toReplace *regexp.Regexp
replaceWith string
}
func NewCaseInsensitiveReplacer(toReplace, replaceWith string) *CaseInsensitiveReplacer {
return &CaseInsensitiveReplacer{
toReplace: regexp.MustCompile("(?i)" + toReplace),
replaceWith: replaceWith,
}
}
func (cir *CaseInsensitiveReplacer) Replace(str string) string {
return cir.toReplace.ReplaceAllString(str, cir.replaceWith)
}
And then used via:
r := NewCaseInsensitiveReplacer("html", "xml")
fmt.Println(r.Replace("This is <b>HTML</b>!"))
Here's a link to an example in the playground.

Based on the documentation it does not.
I am not sure about the best way, but you can do this with replace in regular expressions and make it case-insensitive with i flag

Related

Creating a substring in go creates a new kind of symbol

I am comparing strings and there is the following:
Please note that the " in front of NEW are different.
Now when calling my function like this:
my_func(a[18:], b[18:])
The resulting strings are surprisingly:
What do I have to do to cut this weird symbol away and why is it behaving like this?
Because that type of quote is a multibyte character, and you are splitting the string in the middle of a character. What you could do is convert to an []rune and then convert back:
https://play.golang.org/p/pw42sEwRTZd
s := "H界llo"
fmt.Println(s[1:3]) // ��
fmt.Println(string([]rune(s)[1:3])) // 界l
Another option is the utf8string package:
package main
import "golang.org/x/exp/utf8string"
func main() {
s := utf8string.NewString(` 'Not Available') “NEW CREDIT" FROM customers;`)
t := s.Slice(18, s.RuneCount())
println(t == `“NEW CREDIT" FROM customers;`)
}
https://pkg.go.dev/golang.org/x/exp/utf8string

GO flag pkg reading option string containing escaped runes like "\u00FC" won't read

The test program below works as desired using the DEFAULT string having code points like \u00FC,
as well as if that type of code point is coded as a sting within the prog. Passing the same string from cmd line like: prog.exe -input="ABC\u00FC" does NOT. I assumed it was os interaction so
tried other quoting, even wrapping like: "(ABC\u00FC)" and trimming the parens inside the func NG.
Is the "for _, runeRead := range []rune" incorrect for escaped values?
package main
import (
"fmt"
"flag"
"os"
)
var input string
var m = make(map[rune]struct{})
func init() {
flag.StringVar(&input, "input", "A7\u00FC", "string of runes")
m['A'] = struct{}{}
m['\u00FC'] = struct{}{}
m['7'] = struct{}{}
}
func main() {
flag.Parse()
ck(input) // cmd line - with default OK
ck("A\u00FC") // hard code - OK
}
func ck(in string) {
for _, runeRead := range []rune(in) {
fmt.Printf("DEBUG: Testing rune: %v %v\n", string(runeRead), byte(runeRead))
if _, ok := m[runeRead]; ! ok {
fmt.Printf("\nERROR: Invalid entry <%v>, in string <%s>.\n", string(runeRead), in)
os.Exit(9)
}
}
}
Soluntion needs to work windows and linux.
https://ss64.com/nt/syntax-esc.html
^ Escape character.
Adding the escape character before a command symbol allows it to be treated as ordinary text.
When piping or redirecting any of these characters you should prefix with the escape character: & \ < > ^ |
e.g. ^\ ^& ^| ^> ^< ^^
So you should do
prog.exe -input="ABC^\u00FC"
in case it helps others
It apparently is that different OSs and/or shells (in my case bash) are having issue with the the "\u" of the unicode character. In bash at the cmd line the user could enter
$' the characters ' to protect the \u. It was suggested that WITHIN the program if a string had the same issue that the strconv.Quote could have been a solution.
Since I wanted an OS/shell independent solution for non-computer savvy users, I did a slightly more involved workaround.
I tell users to enter the unicode that needs the \u format to use %FC instead of \u00FC. I parse the string from the command line i.e. ABC%FC%F6123 with rexexp and inside my GO code I replace the %xx with the unicode rune as I had originally expected to get it. With a few lines of code the user input is now OS agnostic.

golang convert "type []string" to string

I see some people create a for loop and run through the slice as to create a string, is there an easier way to convert a []string to a string?
Will sprintf do it?
You can use strings.Join(arr \[\]string, separator string) string.
This is a simple example, which you can paste into the main function:
stringArray := []string {"Hello","world","!"}
justString := strings.Join(stringArray," ")
fmt.Println(justString)
And link to working example on playground.
Or using very simple function
simple function
Will Sprint do it?
Yes indeed!
Here is another way to convert to a string if all you care about is that it is a string and not specifically how it looks (see answers above with strings.Join for a little more flexibility).
The advantage of this method (or variations such as Sprintf), is it will work with (almost) every other data such as maps and structs and any custom type that implements the fmt.Stringer inteface.
stringArray := []string {"Hello","world","!"}
justString := fmt.Sprint(stringArray)
Here is a link to a working example.
It can be done easily using Join function by importing strings package. You need to pass the slice of strings and the separator you need to separate the elements in the string. (examples: space or comma)
func Join(elems []string, sep string) string
Example Code :
package main
import (
"fmt"
"strings"
)
func main() {
sliceStr := []string{"a","b","c","d"}
str := strings.Join(sliceStr,", ")
fmt.Println(str)
}
//output: a, b, c, d
If you don't care about the separator, you can use path:
package main
import "path"
func main() {
a := []string{"south", "north"}
s := path.Join(a...)
println(s == "south/north")
}
https://golang.org/pkg/path#Join
package main
import (
"fmt"
"reflect"
"strings"
)
func main() {
str1 := []string{"Trump", "In", "India", "On", "Feb 25"}
fmt.Println(str1)
fmt.Println(reflect.TypeOf(str1))
str2 := strings.Join(str1, " ")
fmt.Println(str2)
fmt.Println(reflect.TypeOf(str2))
str3 := strings.Join(str1, ", ")
fmt.Println(str3)
fmt.Println(reflect.TypeOf(str3))
}
Below is the ouput of the above program :-
go run hello.go
[Trump In India On Feb 25]
[]string
Trump In India On Feb 25
string
Trump, In, India, On, Feb 25
string
In the above code, first, we have defined a slice of string and then use the reflect package to determine the datatype of the slice.
We have imported the “strings” module. With strings.Join() method, and we combine all elements of a string slice into a string. So, Golang string.Join() function that converts slice to string. We have passed the space(” “) as a delimiter. So we will join the slice elements by space.
The second argument to strings.Join() is the delimiter. For no delimiter, please use an empty string literal.
In the next step, we have again used the TypeOf() function to check the data type.
Then we have used the Golang string.Join() function again, but this time, we have passed (,) Comma. So, command separated values will be returned, which is also a type of string.
So, if you want to get CSV values in Golang, then you can use the Go string.Join() method.
You can also try with functions:-
// abc.go
package main
type deck []string
func (cards deck) toString() string {
// converts slice to string
return strings.Join([]string(cards), ",")
}
//main.go
package main
import "fmt"
func main() {
cards := []string {"Trump", "In", "India", "On", "Feb 25"}
fmt.Println(cards.toString())
}

Go StartsWith(str string)

Is there a StartsWith(str1, str2 string) function that can check if str1 is a prefix of str2 in Go language?
I want a function similar to the Java's startsWith().
The strings package has what you are looking for. Specifically the HasPrefix function: http://golang.org/pkg/strings/#HasPrefix
Example:
fmt.Println(strings.HasPrefix("my string", "prefix")) // false
fmt.Println(strings.HasPrefix("my string", "my")) // true
That package is full of a lot of different string helper functions you should check out.
For Example
If you want to check if a string starts with a dot
package main
import "strings"
func main() {
str := ".com"
fmt.Println(strings.HasPrefix(str, "."))
}
Terminal:
$ true

Remove Characters from the end of a String Scala

What is the simplest method to remove the last character from the end of a String in Scala?
I find Rubys String class has some very useful methods like chop. I would have used "oddoneoutz".headOption in Scala, but it is depreciated. I don't want to get into the overly complex:
string.slice(0, string.length - 1)
Please someone tell me there is a nice simple method like chop for something this common.
How about using dropRight, which works in 2.8:-
"abc!".dropRight(1)
Which produces "abc"
string.init // padding for the minimum 15 characters
val str = "Hello world!"
str take (str.length - 1) mkString
If you want the most efficient solution than just use:
str.substring(0, str.length - 1)
string.reverse.substring(1).reverse
That's basically chop, right? If you're longing for a chop method, why not write your own StringUtils library and include it in your projects until you find a suitable, more generic replacement?
Hey, look, it's in commons.
Apache Commons StringUtils.
If you want just to remove the last character use .dropRight(1). Alternatively, if you want to remove a specific ending character you may want to use a match pattern as
val s: String = "hello!"
val sClean: String = s.takeRight(1) match {
case "!" => s.dropRight(1)
case _ => s
}

Resources