In TCL what is the difference between string "match" and string "equal".
They are almost same so I am not able to detect the difference between them.
string equal compares two strings character by character and returns 1 if they both contain the same characters (case sensitive: can be overridden).
string match compares a string against a glob-style pattern and returns 1 if the string matches the pattern.
In a degenerate case, a string match with only non-special characters in the pattern is equivalent to a string equal.
Documentation:
string
Syntax of Tcl string matching:
* matches a sequence of zero or more characters
? matches a single character
[chars] matches a single character in the set given by chars (^ does not negate; a range can be given as a-z)
\x matches the character x, even if that character is special (one of *?[]\)
already answered in
TCL string match vs regexps
Regexp are slower than base function. So you should avoid regex for equal check
Related
Say I have a pattern, and a string:
String = "ABCDEF"
Pattern = "%w%w%w - %w%w%w"
How can I make String match the format of Pattern, so it becomes "ABC - DEF"?
Use string.gsub:
string.gsub("ABCDEF", "(%w%w%w)(%w%w%w)", "%1 - %2")
Note that this would replaces all the occurrences of the pattern.
There no one to one match beetween string, pattern and capture.
Same capture can be produced by several patterns for same string.
Also if "%w%w%w - %w%w%w" in your example is Lua string pattern then
string "ABC - DEF" does not match to it. Patterns that match to it can be
%w%w%w %- %w%w%w or %w+%W+%w+ or %w*%s*.%s*%w* or several others.
So I suggest define your own subset of rules that you really need and
implement your own function to handle it.
I'm trying to find exact matches of strings in Lua including, special characters. I want the example below to return that it is an exact match, but because of the - character it returns nil
index = string.find("test-string", "test-string")
returns nil
index = string.find("test-string", "test-")
returns 1
index = string.find("test-string", "test")
also returns 1
How can I get it to do full matching?
- is a pattern operator in a Lua string pattern, so when you say test-string, you're telling find() to match the string test as few times as possible. So what happens is it looks at test-string, sees test in there, and since - isn't an actual minus sign in this case, it's really looking for teststring.
Do as Mike has said and escape it with the % character.
I found this helpful for better understanding patterns.
You can also ask for a plain substring match that ignores magic characters:
string.find("test-string", "test-string",1,true)
you need to escape special characters in the pattern with the % character.
so in this case you are looking for
local index = string.find('test-string', 'test%-string')
I want to compare the first letter of a string with a known character. For example, I want to check if the string "example"'s first letter matches with "e" or not. I'm sure there must be a very simple way to do it, but I could not find it.
One way is to get the first character with string index:
if {[string index $yourstring 0] eq "e"} {
...
I think it's a good idea to collect the different methods in a single answer.
Assume
set mystring example
set mychar e
The goal is to test whether the first character in $mystring is equal to $mychar.
My suggestion was (slightly edited):
if {[string match $mychar* $mystring]} {
...
This invocation does a glob-style match, comparing $mystring to the character $mychar followed by a sequence of zero or more arbitrary characters. Due to shortcuts in the algorithm, the comparison stops after the first character and is quite efficient.
Donal Fellows:
if {[string index $mystring 0] eq $mychar} {
...
This invocation specifically compares a string consisting of the first character in $mystring with the string $mychar. It uses the efficient eq operator rather than the == operator, which is the only one available in older versions of Tcl.
Another way to construct a string consisting of the first character in $mystring is by invoking string range $mystring 0 0.
Mark Kadlec:
if {[string first $mychar $mystring] == 0 }
...
This invocation searches the string $mystring for the first occurrence of the character $mychar. If it finds any, it returns with the index where the character was found. This index number is then compared to 0. If they are equal the first character of $mystring was $mychar.
This solution is rather inefficient in the worst case, where $mystring is long and $mychar does not occur in it. The command will then examine the whole string even though only the first character is of interest.
One more string-based solution:
if {[string compare -length 1 $mychar $mystring] == 0} {
...
This invocation compares the first n characters of both strings (n being hardcoded to 1 here): if there is a difference the command will return -1 or 1 (depending on alphabetical order), and if they are equal 0 will be returned.
Another solution is to use a regular expression match:
if {[regexp -- ^$mychar.* $mystring]} {
...
This solution is similar to the string match solution above, but uses regular expression syntax rather than glob syntax. Don't forget the ^ anchor, otherwise the invocation will return true if $mychar occurs anywhere in $mystring.
Documentation: eq and ==, regexp, string
if { [string first e $yourString] == 0 }
...
set mychar "e"
if { [string first $mychar $myString] == 0}{
....
I simply want to check if all the letters that occur in a string are upper-case (if they have lower- and upper-case variants). Tcl's built-in procs don't behave quite as desired, e.g.,
string is upper "123A"
returns false, but I would want it to return true. I would also want it to return true if the A were replaced with, say, an upper-case Cyrillic letter, or a letter from another popular alphabet that doesn't have a case. I could simply filter out all non-letters from the string, but that's not so simple I think when you're trying to handle letters from languages other than just English.
In this case, you don't want string is upper as that checks if the string is just upper case letters. (Numbers aren't letters.)
Instead, you want to do:
set str "123A"
if {$str eq [string toupper $str]} {
# It's upper-case by your definition...
}
I have the following requirements for validating an input field:
It should only contain alphabetical characters and spaces.
It cannot contain spaces at the beginning or end of the string.
It cannot contain any other special character.
For example, the expression should accept the following string "my name is wish".
The regular expression which I'm using is:
RegExp.Pattern = "^[\a-zA-Z]*[\s]*[\a-zA-Z]*[\s]*[\a-zA-Z]*$"
When I enter a name as "abc abc abc6" it accepts it as valid. It should give an error since a number is entered.
Try this pattern
^[a-zA-Z]+(?:\s+[a-zA-Z]+)*$
Explanation of pattern:
^ Start of string
[a-zA-Z] Any character in the class a to z or A to Z
+ One or more repititions
(?: ) Match expresion but don't capture
\s+ Whitespace, One or more repititions
* Zero or more repititions
$ End of string