Case insensitive string compare

How do I compare 2 strings ignoring case? TIA.

gw:

All you need to do is set variables to the strings you want to compare, and then use the [is] and [is not] operands to return true or false:


set a to "abce"
set b to "dfgt"
(a is b) & return & (a is not b)

You can also use the operand [contains] to see if a string contains another string:

set a to "abce"
set b to "dfgt"
set c to "fg"
(a is b) & (a is not b) & (b contains c)

Hope this helps. If not, describe what you need and I or someone else can go from there.

casdvm

I think the issue is “ignoring case”, not “comparing strings”.

For instance, if a .log file exists, I want to move it to another folder. But sometimes they get a .LOG extension. So, without a case-insensitive specifier, I have to give two separate identifiers for log files: .log and .LOG.

Perl and many other languages have “switches” that turn off case sensitivity. Is there some such feature in Applescript’s string handling?

considering case
	"LOG" = "log" --> Returns: false
end considering

ignoring case
	"LOG" = "log" --> Returns: true
end ignoring

j

AppleScript compares strings case-insensitively by default. What’s the context where the problem occurs?

Thanks for the replies. I’m searching a list:

on SearchList(needle, haystack)
	repeat with i from 1 to count of haystack
		if needle is equal to item i of haystack then return i
	end repeat
	return 0
end SearchList

When I seach ‘haystack’ which contains the string “IT” with ‘needle’ which is the string “it”, it returns nothing. The same seems to be true with other mixed case compares. However, I will try the ‘ignorning’ mode and get back to you.

The ‘ignoring case’ doesn’t help either but the light just dawned rereading the replies. What is the difference between:

string1 is equal to string 2

and

string1 = string2

OK, apparently there is no difference. In my case both fail unless the strings match including case. I also checked for leading and trailing spaces but other then case, the ‘unequal’ strings are identical. Any ideas how to shoot this bug?

the problem with the script is not with the case sensativity but in the return line. The way that you have it the handler stops and returns the index in the list of the first item that it comes across and exits the handler. If you are looking for a count then do the following:

set needle to "it"
set haystack to {"it", "IT", "These"}
on SearchList(needle, haystack)
	set z to 0
	repeat with i from 1 to count of haystack
		if needle = item i of haystack then set z to z + 1
	end repeat
	return z
end SearchList
set y to SearchList(needle, haystack)

the following will return a list of items (indexed in the lis haystack) that meet the test:

set needle to "it"
set haystack to {"test", "it", "IT", "These", "It"}
on SearchList(needle, haystack)
	set z to {}
	repeat with i from 1 to count of haystack
		if needle = item i of haystack then set z to z & i
	end repeat
	return z
end SearchList
set y to SearchList(needle, haystack)

I would imagine that one of these is the result that you are looking for, most likely the second.

Thanks. All the strings in the list are unique and I do indeed want the function to return the index of the matched item. However, using ‘display dialog’ I can see the value of ‘needle’ is “it” and there is a compare on an item in the list which is “IT”. That compare does not return. To make sure there are no unprintable characters I did this:

display dialog "!" & needle & "!" & item i of haystack & "!"

The display on the item of interest was “!it!IT!”. However, it did not return but continued comparing until the repeat ended. Note that when I tried “!IT!IT” the compare suceeded and returned. Again ‘ignoring case’ made no difference. Something bizare is going on here.

I’m not sure I follow…

When I run my second script above I have a list of numbers that is returned by the handler. These values {2, 3, 5} corespond to the item number in haystack that are equil to needle {“test”, “it”, “IT”, “These”, “It”}. Note that item 2 is “it”, item 3 is “IT” and item 5 is “It”, all of which meet are equil to the “it” value of needle. From what I can see this is what you want. If you exit out of the script in the if statement as you did in the handler that you posted then it would return the value of i for the first item in haystack that meets the test, which in this case would be item 2, and then exit the handler. It seems to work for me using this:

set needle to "it"
set haystack to {"test", "to", "IT", "These", "It"}
on SearchList(needle, haystack)
	repeat with i from 1 to count of haystack
		if needle is equal to item i of haystack then return i
	end repeat
	return 0
end SearchList
set y to SearchList(needle, haystack)

which returns the value of i of 3 which is the index of “IT” in the list. The handler never gets to the 5th itme “It” which also is equil to “it”.

I can’t, for the life of me, see the difference between yours and mine. The ‘display dialog’ showed the correct data but yet mine fails (other then I used “is equal to” instead of “=”, although neither works for me). I call this from within a ‘Tell Application “Address Book”’. Could that have someting to do with it?

I think I’m on to something here. I tried comparing ‘needle’ to ‘it’ and even that failed. I have to assume, at this point, that there is some non-displayable character in needle. Is there a way to display ‘needle’ in hex to see all the characters?

set x to count of characters of needle should tell you if there are more than the expected. A thought, the value returned from address book may need to be coerced to a string.

Well, even a blind squirrel finds and occasional nut. I don’t pretend to understand it but in a ‘tell application “Address Book”’ the following is apparently required:

if (needle as string) is equal to ((item i of haystack) as string) then return i

I don’t use address book on this computer so I dont have a list to work with. However looking at the dictionary the value returned for most items, like last name, are unicode text and that is probably the reason that it needs to be coerced to a string.