I have the same problem like in this question:
How do I check if a string contains another string in Swift?
But now a few months later I wonder if it can be done without using NSString?
I nice and simple contains-method would be fine.
I searched the web and the documentation but I found nothing!
Same way, just with Swift syntax:
let string = "This is a test. This is only a test"
if string.rangeOfString("only") != nil {
println("yes")
}
For Swift 3.0
if str.range(of: "abc") != nil{
print("Got the string")
}
String actually provides a "contains" function through StringProtocol.
No extension whatsoever needed:
let str = "asdf"
print(str.contains("sd") ? "yep" : "nope")
https://developer.apple.com/reference/swift/string
https://developer.apple.com/documentation/swift/stringprotocol
If you want to check if your string matches a specific pattern, I can recommend the NSHipster article about NSRegularExpressions: http://nshipster.com/nsregularexpression/
I wrote an extension on String for SWIFT 3.0 so that i could simply call absoluteString.contains(string: "/kredit/")
extension String {
public func contains(string: String)-> Bool {
return self.rangeOfString(string) != nil
}
}
just to demonstrate the use of options.
var string = "This is a test. This is only a test. Not an Exam"
if string.range(of:"ex") != nil {
print("yes")
}
if string.range(of:"ex", options: String.CompareOptions.caseInsensitive) != nil {
print("yes")
}
Related
I am having a String that i would like to convert to Boolean Below is how the string looks like
String isValid = "false";
The String isValid can either be true or false
Is there a way i can directly convert this String isValid to Boolean. I have tried Sample questions and solutions but they are just converting Strings which are hard coded, for example most of the answers are just when the string is true
On top of my head, you can create an extension method for string data-type for your own need with all sorts of requirements checks and custom exceptions to beautify your desired functionalities. Here is an example:
import 'package:test/expect.dart';
void main(List<String> args) {
String isValid = "true";
print(isValid.toBoolean());
}
extension on String {
bool toBoolean() {
print(this);
return (this.toLowerCase() == "true" || this.toLowerCase() == "1")
? true
: (this.toLowerCase() == "false" || this.toLowerCase() == "0"
? false
: throwsUnsupportedError);
}
}
Here, in this example, I've created a variable named isValid in the main() method, which contains a string value. But, look closely at how I've parsed the string value to a bool value using the power with extension declared just a few lines below.
Same way, you can access the newly created string-extension method toBoolean() from anywhere. Keep in mind, if you're not in the same file where the toBoolean() extension is created, don't forget to import the proper reference.
Bonus tips:
You can also access toBoolean() like this,
bool alternateValidation = "true".toBoolean();
Happy coding 😊
This example can work for you, either if is false or true:
String isValid = "true";
bool newBoolValue = isValid.toLowerCase() != "false";
print(newBoolValue);
You can use extensions like this
bool toBoolean() {
String str = this!;
return str != '0' && str != 'false' && str != '';
}
First of All
You should make the string to lowercase to prevent check the string twice
then you can check if the string equal "true" or not and save the result to bool variable as below:
String isValidString = "false"; // the boolean inside string
bool isValid = isValidString.toLowerCase() == 'true'; // check if true after lowercase
print("isValid=$isValid"); // print the result
I opened a PR for this question, I believe that in the future it will be possible to do something native.
void main() {
print(bool.parse("true")); // true
print(bool.parse("false")); //false
print(bool.parse("TRUE")); // FormatException
print(bool.parse("FALSE")); //FormatException
print(bool.parse("True", caseSensitive: false)); // true
print(bool.parse("False", caseSensitive: false)); // false
if(bool.parse("true")){
//code..
}
}
Reference
https://github.com/dart-lang/sdk/pull/51026
Looking for code that will do conversions like this:
"MyCamelCaseA" to "my_camel_case_a"
"AMultiWordString" to "a_multi_word_string"
"my_camel_case_a" to "myCamelCaseA" or "MyCamelCaseA"
"a_multi_word_string" to "aMultiWordString" or "AMultiWordString"
Here are extensions to the String class that use regex and replacements to convert a string from camel case to snake case, and from snake case to camel case:
val camelRegex = "(?<=[a-zA-Z])[A-Z]".toRegex()
val snakeRegex = "_[a-zA-Z]".toRegex()
// String extensions
fun String.camelToSnakeCase(): String {
return camelRegex.replace(this) {
"_${it.value}"
}.toLowerCase()
}
fun String.snakeToLowerCamelCase(): String {
return snakeRegex.replace(this) {
it.value.replace("_","")
.toUpperCase()
}
}
fun String.snakeToUpperCamelCase(): String {
return this.snakeToLowerCamelCase().capitalize()
}
Here are examples using the String extension:
print("${"MyCamelCaseA".camelToSnakeCase()}\n")
my_camel_case_a
print("${"AMultiWordString".camelToSnakeCase()}\n")
a_multi_word_string
"my_camel_case_a".snakeToLowerCamelCase()
myCamelCaseA
"my_camel_case_a".snakeToUpperCamelCase()
MyCamelCaseA
Here's my stab at this.
fun String.camelToSnakeCase() = fold(StringBuilder(length)) { acc, c ->
if (c in 'A'..'Z') (if (acc.isNotEmpty()) acc.append('_') else acc).append(c + ('a' - 'A'))
else acc.append(c)
}.toString()
My approach is also written in the form of extension function, but it does not use regular expressions, instead going character-by-character, processing them and folding the processing result into the accumulator, which at the beginning is an empty StringBuilder. The processing is as follows:
if the character is not an upper-case Latin letter, add it to accumulator as is
if the character is an upper-case Latin letter, then also check if this is not the first character of the string (accumulator is not empty). If it is not, then add underscore to accumulator. Finally add lower-cased character.
One thing to note, is that kotlin.text.StringBuilder is used, not the JDK one.
I would go with these implementations:
fun String.toCamelCase() =
split('_').joinToString("", transform = String::capitalize)
... which splits the string using snakes as delimiters, and then reattaches the parts as capitalized words without a delimiter.
fun String.toSnakeCase() = replace(humps, "_").toLowerCase()
private val humps = "(?<=.)(?=\\p{Upper})".toRegex()
... which uses a regex to find the positions before humps, inserting snakes, and then converts the whole string to lowercase. The regex consists of two parts, the first one (?<=.) is a positive look-behind saying that it must be preceded by a character, and the second part (?=\\p{Upper}) is using a positive look-ahead saying it must be followed by an uppercase character.
If you have jackson-databind in your classpath, you can use the following utility function:
import com.fasterxml.jackson.databind.PropertyNamingStrategies
fun String.toSnakeCase(): String =
PropertyNamingStrategies.SnakeCaseStrategy().translate(this)
fun main() {
// should output this_is_the_case
println("thisIsTheCase".toSnakeCase())
}
this is my try with kotlin only
val camelCaseString = "thisIsCamelCase"
val snakeCaseString = camelCaseString.map {
if (it.isUpperCase()){
"_${it.toLowerCase()}"
}else
{"$it"}
}
.joinToString(separator = "")
System.out.println("here is your snake string: $snake_case_string")
here is your snake string: this_is_camel_case
convert from snake to camel
val snakeCaseString = "snake_case_string"
val camelCase = StringBuilder()
var prevChar = '$'
snakeCaseString.forEach {
if(prevChar.equals('_')){
camelCase.append(it.toUpperCase())
}else if(!it.equals('_')){
camelCase.append(it)
}
prevChar = it
}
System.out.println(camelCase.toString())
snakeCaseString
I took one of the answers here, added Title Case and changed the API a bit
val camelRegex = "(?<=[a-zA-Z])[A-Z]".toRegex()
val snakeRegex = "_[a-zA-Z]".toRegex()
#JvmInline
value class SnakeCaseString(private val string: String) {
fun toCamelCase(): String = snakeRegex.replace(string) { it.value.replace("_", "").uppercase() }
fun toUpperCamelCase(): String =
toCamelCase().replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
fun toTitleCase(): String = snakeRegex.replace(string) { it.value.replace("_", " ").uppercase() }
.replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
}
#JvmInline
value class CamelCaseString(private val string: String) {
fun toSnakeCase(): String = camelRegex.replace(string) { "_${it.value}" }.lowercase()
fun toTitleCase(): String = camelRegex.replace(string) { "_${it.value}" }
.replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
}
fun String.asSnakeCase() = SnakeCaseString(this)
fun String.asCamelCase() = CamelCaseString(this)
If you want a method with an input and output, this is how I did it:
private fun convertCamelToSnakeCase(camelCase : String) : String {
val snakeCase = StringBuilder()
for(character in camelCase) {
if(character.isUpperCase()) {
snakeCase.append("_${character.toLowerCase()}")
} else {
snakeCase.append(character)
}
}
return snakeCase.removePrefix("_").toString()
}
How do I check if a String includes a specific Character?
For example:
if !emailString.hasCharacter("#") {
println("Email must contain at sign.")
}
You can use the free-standing find function, like this:
let s = "hello"
if (find(s, "x") != nil) {
println("Found X")
}
if (find(s, "l") != nil) {
println("Found L")
}
Here you go:
if emailString.rangeOfString("#") != nil{
println("# exists")
}
You can use this
if emailString.rangeOfString("#") == nil {
println("Email must contain at sign.")
}
If I declared a String like this: var date = String()
and I want to check if it is a nil String or not,
so that I try something like:
if date != nil{
println("It's not nil")
}
But I got an error like : Can not invoke '!=' with an argument list of type '(#lvalue String, NilLiteralConvertible)'
after that I try this:
if let date1 = date {
println("It's not nil")
}
But still getting an error like:
Bound value in a conditional binding must be of Optional type
So my question is how can I check that the String is not nil if I declare it this way?
The string can't be nil. That's the point of this sort of typing in Swift.
If you want it to be possibly nil, declare it as an optional:
var date : String?
If you want to check a string is empty (don't do this, it's the sort of thing optionals were made to work around) then:
if date.isEmpty
But you really should be using optionals.
You may try this...
var date : String!
...
if let dateExists = date {
// Use the existing value from dateExists inside here.
}
Happy Coding!!!
In your example the string cannot be nil. To declare a string which can accept nil you have to declare optional string:
var date: String? = String()
After that declaration your tests will be fine and you could assign nil to that variable.
Its a bit late but might help others. You can create an optional string extension. I did the following to set an optional string to empty if it was nil :
extension Optional where Wrapped == String {
mutating func setToEmptyIfNil() {
guard self != nil else {
self = ""
return
}
}
}
I would like to emulate C's sprintf("%02d", x); in Dart, but I can't find string formatting, only string interpolation.
String interpolation covers most of your needs. If you want to format numbers directly, there is also num.toStringAsPrecision().
I took a different approach to this issue: by padding the string directly, I don't have to use any libraries (mainly because the intl library seems to be discontinued):
x.toString().padLeft(2, "0");
Would be the equivalent of sprintf("%02d", x);
The intl library provides several helpers to format values.
See the API documentation at http://api.dartlang.org/docs/releases/latest/intl.html
Here is an example on how to convert a number into a two character string:
import 'package:intl/intl.dart';
main() {
var twoDigits = new NumberFormat("00", "en_US");
print(twoDigits.format(new Duration(seconds: 8)));
}
A String.format method does not currently exists but there is a bug/feature request for adding it.
Here is my implementation of String.format for Dart. It is not perfect but works good enough for me:
static String format(String fmt,List<Object> params) {
int matchIndex = 0;
String replace(Match m) {
if (matchIndex<params.length) {
switch (m[4]) {
case "f":
num val = params[matchIndex++];
String str;
if (m[3]!=null && m[3].startsWith(".")) {
str = val.toStringAsFixed(int.parse(m[3].substring(1)));
} else {
str = val.toString();
}
if (m[2]!=null && m[2].startsWith("0")) {
if (val<0) {
str = "-"+str.substring(1).padLeft(int.parse(m[2]),"0");
} else {
str = str.padLeft(int.parse(m[2]),"0");
}
}
return str;
case "d":
case "x":
case "X":
int val = params[matchIndex++];
String str = (m[4]=="d")?val.toString():val.toRadixString(16);
if (m[2]!=null && m[2].startsWith("0")) {
if (val<0) {
str = "-"+str.substring(1).padLeft(int.parse(m[2]),"0");
} else {
str = str.padLeft(int.parse(m[2]),"0");
}
}
return (m[4]=="X")?str.toUpperCase():str.toLowerCase();
case "s":
return params[matchIndex++].toString();
}
} else {
throw new Exception("Missing parameter for string format");
}
throw new Exception("Invalid format string: "+m[0].toString());
}
Test output follows:
format("%d", [1]) // 1
format("%02d", [2]) // 02
format("%.2f", [3.5]) // 3.50
format("%08.2f", [4]) // 00004.00
format("%s %s", ["A","B"]) // A B
format("%x", [63]) // 3f
format("%04x", [63]) // 003f
format("%X", [63]) //3F
Yes, Dart has a sprintf package:
https://pub.dev/packages/sprintf.
It is modeled after C's sprintf.
See a format package. It is similar to format() from Python. It is a new package. Needs testing.