Lua strings 'n' things - string

New to Lua, need to check if a string exists inside another string, and can't seem to figure it out, how do I?
In PHP this'd be:
<?php
$pos = strpos($haystack,$needle);
if($pos === false) {
// string needle NOT found in haystack
} else {
// string needle found in haystack
}
?>
Also need to chop off the last char of a string...

http://lua-users.org/wiki/StringLibraryTutorial
print(string.find("foobar", "foo"))
yields...
1 3
print(string.find("foobar", "baz"))
yields...
nil
print(string.sub("foobar", 1, 5))
yields...
fooba

For chopping the last character, you can use a negative index:
string.sub("the string.", 1, -2)

Related

Making sure every Alphabet is in a string (Kotlin)

So I have a question where I am checking if a string has every letter of the alphabet in it. I was able to check if there is alphabet in the string, but I'm not sure how to check if there is EVERY alphabet in said string. Here's the code
fun isPangram (pangram: Array<String>) : String {
var panString : String
var outcome = ""
for (i in pangram.indices){
panString = pangram[i]
if (panString.matches(".^*[a-z].*".toRegex())){
outcome = outcome.plus('1')
}
else {outcome = outcome.plus('0')}
}
return outcome
}
Any ideas are welcomed Thanks.
I think it would be easier to check if all members of the alphabet range are in each string than to use Regex:
fun isPangram(pangram: Array<String>): String =
pangram.joinToString("") { inputString ->
when {
('a'..'z').all { it in inputString.lowercase() } -> "1"
else -> "0"
}
}
Hi this is how you can make with regular expression
Kotlin Syntax
fun isStrinfContainsAllAlphabeta( input: String) {
return input.lowercase()
.replace("[^a-z]".toRegex(), "")
.replace("(.)(?=.*\\1)".toRegex(), "")
.length == 26;
}
In java:
public static boolean isStrinfContainsAllAlphabeta(String input) {
return input.toLowerCase()
.replace("[^a-z]", "")
.replace("(.)(?=.*\\1)", "")
.length() == 26;
}
the function takes only one string. The first "replaceAll" removes all the non-alphabet characters, The second one removes the duplicated character, then you check how many characters remained.
Just to bounce off Tenfour04's solution, if you write two functions (one for the pangram check, one for processing the array) I feel like you can make it a little more readable, since they're really two separate tasks. (This is partly an excuse to show you some Kotlin tricks!)
val String.isPangram get() = ('a'..'z').all { this.contains(it, ignoreCase = true) }
fun checkPangrams(strings: Array<String>) =
strings.joinToString("") { if (it.isPangram) "1" else "0" }
You could use an extension function instead of an extension property (so it.isPangram()), or just a plain function with a parameter (isPangram(it)), but you can write stuff that almost reads like English, if you want!

Replacing the number in a string

if my string is lets say "Alfa1234Beta"
how can I convert all the number in to "_"
for example "Alfa1234Beta"
will be "Alfa____Beta"
Going with the Regex approach pointed out by others is possibly OK for your scenario. Mind you however, that Regex sometimes tend to be overused. A hand rolled approach could be like this:
static string ReplaceDigits(string str)
{
StringBuilder sb = null;
for (int i = 0; i < str.Length; i++)
{
if (Char.IsDigit(str[i]))
{
if (sb == null)
{
// Seen a digit, allocate StringBuilder, copy non-digits we might have skipped over so far.
sb = new StringBuilder();
if (i > 0)
{
sb.Append(str, 0, i);
}
}
// Replace current character (a digit)
sb.Append('_');
}
else
{
if (sb != null)
{
// Seen some digits (being replaced) already. Collect non-digits as well.
sb.Append(str[i]);
}
}
}
if (sb != null)
{
return sb.ToString();
}
return str;
}
It is more light weight than Regex and only allocates when there is actually something to do (replace). So, go ahead use the Regex version if you like. If you figure out during profiling that is too heavy weight, you can use something like the above. YMMV
You can run for loop on the string and then use the following method to replace numbers with _
if (!System.Text.RegularExpressions.Regex.IsMatch(i, "^[0-9]*$"))
Here variable i is the character in the for loop .
You can use this:
var s = "Alfa1234Beta";
var s2 = System.Text.RegularExpressions.Regex.Replace(s, "[0-9]", "_");
s2 now contains "Alfa____Beta".
Explanation: the regex [0-9] matches any digit from 0 to 9 (inclusive). The Regex.Replace then replaces all matched characters with an "_".
EDIT
And if you want it a bit shorter AND also match non-latin digits, use \d as a regex:
var s = "Alfa1234Beta๓"; // ๓ is "Thai digit three"
var s2 = System.Text.RegularExpressions.Regex.Replace(s, #"\d", "_");
s2 now contains "Alfa____Beta_".

Get the first line of a string in haxe

Let's assume we have a multiline string, like
var s:String = "my first line\nmy second line\nmy third line\nand so on!";
What is the best way to get (only) the first line of this string in Haxe? I know I can do something like:
static function getFirstLine(s:String):String {
var t:String = s.split("\n")[0];
if(t.charAt(t.length - 1) == "\r") {
t = t.substring(0, t.length - 1);
}
return t;
}
However I'm wondering if there is any easier (predefined) method for this ...
Caveat that #Gama11's answer works well and is more elegant than this.
If your string is long, split will iterate over the whole thing and allocate an array containing every line in your string, both of which are unnecessary here. Another option would be indexOf:
static function getFirstLine(s:String):String {
var i = s.indexOf("\n");
if (i == -1) return s;
if (i > 0 && s.charAt(i - 1) == "\r") --i;
return s.substr(0, i);
}
There's no built-in utility in the standard library for this that I know of, but you make it a bit more elegant and avoid the substring() handling for \r by splitting on a regex:
static function getFirstLine(s:String):String {
return ~/\r?\n/.split(s)[0];
}
The regex \r?\n optionally matches a carriage return followed by a line feed character.

Remove nth character from string

I have seen many methods for removing the last character from a string. Is there however a way to remove any old character based on its index?
Here is a safe Swift 4 implementation.
var s = "Hello, I must be going"
var n = 5
if let index = s.index(s.startIndex, offsetBy: n, limitedBy: s.endIndex) {
s.remove(at: index)
print(s) // prints "Hello I must be going"
} else {
print("\(n) is out of range")
}
While string indices aren't random-access and aren't numbers, you can advance them by a number in order to access the nth character:
var s = "Hello, I must be going"
s.removeAtIndex(advance(s.startIndex, 5))
println(s) // prints "Hello I must be going"
Of course, you should always check the string is at least 5 in length before doing this!
edit: as #MartinR points out, you can use the with-end-index version of advance to avoid the risk of running past the end:
let index = advance(s.startIndex, 5, s.endIndex)
if index != s.endIndex { s.removeAtIndex(index) }
As ever, optionals are your friend:
// find returns index of first match,
// as an optional with nil for no match
if let idx = s.characters.index(of:",") {
// this will only be executed if non-nil,
// idx will be the unwrapped result of find
s.removeAtIndex(idx)
}
Swift 3.2
let str = "hello"
let position = 2
let subStr = str.prefix(upTo: str.index(str.startIndex, offsetBy: position)) + str.suffix(from: str.index(str.startIndex, offsetBy: (position + 1)))
print(subStr)
"helo"
var hello = "hello world!"
Let's say we want to remove the "w". (It's at the 6th index position.)
First: Create an Index for that position. (I'm making the return type Index explicit; it's not required).
let index:Index = hello.startIndex.advancedBy(6)
Second: Call removeAtIndex() and pass it our just-made index. (Notice it returns the character in question)
let choppedChar:Character = hello.removeAtIndex(index)
print(hello) // prints hello orld!
print(choppedChar) // prints w

Go: Retrieve a string from between two characters or other strings

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

Resources