Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I am trying following code to extract quoted part from a string:
package main
import ("fmt")
func main(){
var oristr = "This is a \"test string\" for testing only"
var quotedstr = ""
var newstr = ""
var instring = false
fmt.Println(oristr)
for i,c := range oristr {
fmt.Printf("Char number: %d; char: %c\n", i, c);
if c = `"` {
if instring
{instring=false}
else {instring=true}}
if instring
{quotedstr += c}
else {newstr += c}
}
fmt.Printf("Newstr: %s; quotedstr = %s", newstr, quotedstr )
}
However, I am getting following error:
# command-line-arguments
./getstring.go:11:14: syntax error: c = `"` used as value
./getstring.go:12:15: syntax error: unexpected newline, expecting { after if clause
./getstring.go:14:4: syntax error: unexpected else, expecting }
./getstring.go:15:3: syntax error: non-declaration statement outside function body
Why I am getting this error and how can this be corrected?
Also, is this approach all right or some other approach may be better?
This is the most basic way of getting what you want. It could be improved to be more robust etc.
package main
import (
"fmt"
"regexp"
)
func main() {
var oristr = "This is a \"test string\" for containing multiple \"test strings\" and another \"one\" here"
re := regexp.MustCompile(`"[^"]+"`)
newStrs := re.FindAllString(oristr, -1)
for _, s := range newStrs {
fmt.Println(s)
}
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I tried this code but it is giving me errors. So how can I access a character in a string in kotlin? In java, it can be done by the charAt() method.
private fun abc(x: String) {
var i: Int = 0
while (x[i].toString() != "+") {
var y: Char = x[i]
i++
}
}
The equivalent of Javas String.charAt() in Kotlin is String.get(). Since this is implemented as an operator, you can use [index] instead of get(index). For example
val firstChar: Char = "foo"[0]
or if you prefer
val someString: String = "bar"
val firstChar: Char = someString.get(0)
The beauty of Kotlin is that you can do it in few ways, eg.
You can simply access it by index:
while (x[i] != '+') {
i++
}
Converting to CharArray
val chars: CharArray = x.toCharArray()
while (chars[i] != '+') {
i++
}
You can also use idiomatic Kotlin (preferred):
forEach
x.forEach { c ->
if (c == '+') return#forEach
}
forEachIndexed if you care about index
x.forEachIndexed { index, c ->
if (c == '+') {
println("index=$index")
return#forEachIndexed
}
}
In both cases, your character is accessed with c
Could you please try this method instead?
private fun abc(x: String) {
$p = 1;
do {
$p++
}while (x[p]!= "+")
}
This question already has an answer here:
Trim end off of string in swift, getting error at runtime
(1 answer)
Closed 7 years ago.
Trying to get to grips with Swift programming, I wrote the following:
var s : String = "dog"
var i1 : String.Index = advance(s.startIndex, 2)
var t1 : String = s.substringToIndex(i1)
Executing this code in a playground, t1 has the value "do", as expected. However, if I try to construct an index that exceeds the string's length, this happens:
var s : String = "dog"
var i2 : String.Index = advance(s.startIndex, 4)
var t2 : String = s.substringToIndex(i2)
This time, the line var i2 ... shows the error
Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP,subcode=0x0).
I read the Swift documentation, but the entry for String.substringToIndex reads in its entirety:
func substringToIndex(index: String.Index) -> String
[Foundation]
Returns a new string containing the characters of the String up to, but not including, the one at a given index.
The result is not optional, nor does the function possess an error parameter or return an empty string in case of faulty arguments.
I don't know how to prevent this by not creating an index in the first place, because String does not have a length or count property.
Since Swift does not have exception handling, how can programs recover from errors like this?
This is on OS X 10.10.2, Xcode 6.2.
The error is in advance(s.startIndex, 4) as you cannot advance eyond the end index:
1> var s = "dog"
s: String = "dog"
2> var i1 = advance(s.startIndex, 4)
fatal error: can not increment endIndex
i1: String.Index = {
_base = { /* ... */ }
/* ... */
}
Execution interrupted. Enter Swift code to recover and continue.
Enter LLDB commands to investigate (type :help for assistance.)
You avoid this by providing an end index as:
3> var i1 = advance(s.startIndex, 4, s.endIndex)
i1: String.Index = {
_base = { /* ... */ }
/* ... */
}
and then:
4> s.substringToIndex(i1)
$R0: String = "dog"
at least for Swift1.2, in Xcode6-Beta3.
I have this groovy script that defines a closure that works properly.
escape = { str ->
str.collect{ ch ->
def escaped = ch
switch (ch) {
case "\"" : escaped = "\\\"" ; break
// other cases omitted for simplicity
}
escaped
}.join()
}
assert escape("\"") == "\\\"" //Sucess
But when I add another closure that uses some GString interpolation to the script.
escape = { str ->
//Same as above
}
dummy = {
aStr = "abc"
"123${aStr}456"
}
//Compilation fails
I get the error
javax.script.ScriptException: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script650.groovy: 7: expecting anything but ''\n''; got it anyway # line 7, column 39.
case "\"" : escaped = "\\"" ; break
^
1 error
Even if the added closure was commented.
escape = { str ->
//Same as above
}
/*dummy = {
aStr = "abc"
"123${aStr}456"
}*/
//Compilation fails
Still fails! What gives?
Let's say for example that I have one string, like this:
<h1>Hello World!</h1>
What Go code would be able to extract Hello World! from that string? I'm still relatively new to Go. Any help is greatly appreciated!
If the string looks like whatever;START;extract;END;whatever you can use this which will get the string in between:
// GetStringInBetween Returns empty string if no start string found
func GetStringInBetween(str string, start string, end string) (result string) {
s := strings.Index(str, start)
if s == -1 {
return
}
s += len(start)
e := strings.Index(str[s:], end)
if e == -1 {
return
}
e += s + e - 1
return str[s:e]
}
What happens here is it will find first index of START, adds length of START string and returns all that exists from there until first index of END.
There are lots of ways to split strings in all programming languages.
Since I don't know what you are especially asking for I provide a sample way to get the output
you want from your sample.
package main
import "strings"
import "fmt"
func main() {
initial := "<h1>Hello World!</h1>"
out := strings.TrimLeft(strings.TrimRight(initial,"</h1>"),"<h1>")
fmt.Println(out)
}
In the above code you trim <h1> from the left of the string and </h1> from the right.
As I said there are hundreds of ways to split specific strings and this is only a sample to get you started.
Hope it helps, Good luck with Golang :)
DB
I improved the Jan Kardaš`s answer.
now you can find string with more than 1 character at the start and end.
func GetStringInBetweenTwoString(str string, startS string, endS string) (result string,found bool) {
s := strings.Index(str, startS)
if s == -1 {
return result,false
}
newS := str[s+len(startS):]
e := strings.Index(newS, endS)
if e == -1 {
return result,false
}
result = newS[:e]
return result,true
}
Here is my answer using regex. Not sure why no one suggested this safest approach
package main
import (
"fmt"
"regexp"
)
func main() {
content := "<h1>Hello World!</h1>"
re := regexp.MustCompile(`<h1>(.*)</h1>`)
match := re.FindStringSubmatch(content)
if len(match) > 1 {
fmt.Println("match found -", match[1])
} else {
fmt.Println("match not found")
}
}
Playground - https://play.golang.org/p/Yc61x1cbZOJ
In the strings pkg you can use the Replacer to great affect.
r := strings.NewReplacer("<h1>", "", "</h1>", "")
fmt.Println(r.Replace("<h1>Hello World!</h1>"))
Go play!
func findInString(str, start, end string) ([]byte, error) {
var match []byte
index := strings.Index(str, start)
if index == -1 {
return match, errors.New("Not found")
}
index += len(start)
for {
char := str[index]
if strings.HasPrefix(str[index:index+len(match)], end) {
break
}
match = append(match, char)
index++
}
return match, nil
}
Read up on the strings package. Have a look into the SplitAfter function which can do something like this:
var sample = "[this][is my][string]"
t := strings.SplitAfter(sample, "[")
That should produce a slice something like: "[", "this][", "is my][", "string]". Using further functions for Trimming you should get your solution. Best of luck.
func Split(str, before, after string) string {
a := strings.SplitAfterN(str, before, 2)
b := strings.SplitAfterN(a[len(a)-1], after, 2)
if 1 == len(b) {
return b[0]
}
return b[0][0:len(b[0])-len(after)]
}
the first call of SplitAfterN will split the original string into array of 2 parts divided by the first found after string, or it will produce array containing 1 part equal to the original string.
second call of SplitAfterN uses a[len(a)-1] as input, as it is "the last item of array a". so either string after after or the original string str. the input will be split into array of 2 parts divided by the first found before string, or it will produce array containing 1 part equal to the input.
if after was not found than we can simply return b[0] as it is equal to a[len(a)-1]
if after is found, it will be included at the end of b[0] string, therefore you have to trim it via b[0][0:len(b[0])-len(after)]
all strings are case sensitive
The file names.txt consists of many names in the form of:
"KELLEE","JOSLYN","JASON","INGER","INDIRA","GLINDA","GLENNIS"
Does anyone know how to split the string so that it is individual names separated by commas?
KELLEE,JOSLYN,JASON,INGER,INDIRA,GLINDA,GLENNIS
The following code splits by comma and leaves quotes around the name, what is the escape character to split out the ". Can it be done in one Split statement, splitting out "," and leaving a comma to separate?
package main
import "fmt"
import "io/ioutil"
import "strings"
func main() {
fData, err := ioutil.ReadFile("names.txt") // read in the external file
if err != nil {
fmt.Println("Err is ", err) // print any error
}
strbuffer := string(fData) // convert read in file to a string
arr := strings.Split(strbuffer, ",")
fmt.Println(arr)
}
By the way, this is part of Project Euler problem # 22. http://projecteuler.net/problem=22
Jeremy's answer is basically correct and does exactly what you have asked for. But the format of your "names.txt" file is actually a well known and is called CSV (comma separated values). Luckily, Go comes with an encoding/csv package (which is part of the standard library) for decoding and encoding such formats easily. In addition to your + Jeremy's solution, this package will also give exact error messages if the format is invalid, supports multi-line records and does proper unquoting of quoted strings.
The basic usage looks like this:
package main
import (
"encoding/csv"
"fmt"
"io"
"os"
)
func main() {
file, err := os.Open("names.txt")
if err != nil {
fmt.Println("Error:", err)
return
}
defer file.Close()
reader := csv.NewReader(file)
for {
record, err := reader.Read()
if err == io.EOF {
break
} else if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(record) // record has the type []string
}
}
There is also a ReadAll method that might make your program even shorter, assuming that the whole file fits into the memory.
Update: dystroy has just pointed out that your file has only one line anyway. The CSV reader works well for that too, but the following, less general solution should also be sufficient:
for {
if n, _ := fmt.Fscanf(file, "%q,", &name); n != 1 {
break
}
fmt.Println("name:", name)
}
Split doesn't remove characters from the substrings. Your split is fine you just need to process the slice afterwards with strings.Trim(val, "\"").
for i, val := range arr {
arr[i] = strings.Trim(val, "\"")
}
Now arr will have the leading and trailing "s removed.