I am trying to strip a string of its leading numbers but when I cast a character to a number the script crashes:
Here’s the relevant part of my code:
try
set arrCharacters to every character of strTitle
set strNewTitle to ""
set bIsANumber to true
repeat with idx from 1 to count of every item of arrCharacters
set thisChar to item idx of arrCharacters as string
set bIsANumber to isANumber(item idx of arrCharacters as text)
end repeat
if bIsANumber is equal to false then
set newTitle to text items idx thru (count of every item of arrCharacters) as string
end if
on error errMsg
log errMsg
end try
and the function to check if a char is a number:
on isANumber(strChar)
set aNumber to true
try
set numCheck to strChar as number
on error
set aNumber to false
end try
return aNumber
end isANumber
Hi Stefan.
You need to put the bIsANumber number check inside the repeat so that you can stop repeating when the result’s false
. Also, you may have intended strNewTitle and newTitle to be the same variable.
set strTitle to "12345ABCDE"
set strTitleLength to (count strTitle)
set arrCharacters to every character of strTitle
set newTitle to ""
set bIsANumber to true
repeat with idx from 1 to strTitleLength
set thisChar to item idx of arrCharacters
set bIsANumber to isANumber(thisChar)
if bIsANumber is equal to false then
set newTitle to text idx thru strTitleLength of strTitle
exit repeat
end if
end repeat
return newTitle
on isANumber(strChar)
set aNumber to true
try
set numCheck to strChar as number
on error
set aNumber to false
end try
return aNumber
end isANumber
Stefan. The following script takes a slightly different approach. The script includes error handling, which will not be necessary if the error conditions cannot occur.
--an error dialog is displayed if the strTitle variable is empty or contains numbers only
set strTitle to "12345ABCDE"
try
set newTitle to trimLeadingNumbers(strTitle) -->"ABCDE"
on error
display dialog "The trim numbers handler returned an error" buttons {"OK"} cancel button 1 default button 1
end try
on trimLeadingNumbers(theText)
repeat until text 1 of theText is not in "1234567890"
set theText to text 2 thru -1 of theText
end repeat
return theText
end trimLeadingNumbers
Hey thanks, that’s clever, still curious as to what is causing the crash. Did my code look clean to you?
Hi Nigel - long time fan - I initially tried it that way and it was crashing. I’ll give it a shot tomorrow and let you know - also picked up the errant var name but forgot to update the question. Thanks for reviewing it.
Hi Stefan.
Looking more closely at your original code, I see this is probably because you didn’t specify what the text items
belonged to. So …
set newTitle to text items idx thru (count of every item of arrCharacters) as string
end if
… should have been …
set newTitle to (text items idx thru (count of every item of arrCharacters) of arrCharacters) as string
… except that text items
is more correctly used to extract sections of a single text that come between instances of AppleScript’s current text item delimiter(s):
set AppleScript's text item delimiters to {"is"}
set myText to "This is some text"
return myText's text items --> {"Th", " ", " some text"}
And people often forget that when a list is coerced to text, the first item in the current delimiter list is spliced between the items in the coerced list:
set AppleScript's text item delimiters to {"is"}
set myList to characters of "This is some text"
return myList as text --> "Tishisiissis isiissis issisoismiseis istiseisxist"
It might be as short as this without a repeat loop.
use scripting additions
set s to "12345ABCDE"
-- strip integers from string s
set n to (do shell script "/bin/zsh -c 'print ${0//[0-9]/}' " & s)
“ABCDE”
Hi @VikingOSX.
Your script strips all integers from the string, not just from the beginning. An alternative shell script would be:
set s to "12345ABC6DE7"
-- strip integers from beginning of string s
set n to (do shell script "sed -E 's/^[0-9]+//' <<<" & s's quoted form)
--> "ABC6DE7"
Well Nigel, previous examples were using the string that I used and the submitted results were focused on stripping leading integers, not with retaining embedded or trailing integers. I knew that and understood A Priori that my solution would not retain any integers in the string.
Without using sed, the following modification to my original post will produce your result:
use scripting additions
set s to "12345ABC6DE7"
set n to (do shell script "/bin/zsh -c '[[ \"${0}\" =~ \"([0-9]+)([[:alnum:]]+)$\" ]] && print ${match[2]}' " & s)
“ABC6DE7”
Here is an applescript-only version. It should be pretty quick.
It splits the text on digits and then cycles through the list looking for the first character to persist, and then rejoins the text from that point onward.
set s to "12345ABC6DE7"
set text item delimiters to {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
set tis to text items of s
repeat with ti from 1 to length of tis
if item ti of tis is equal to "" then
else
exit repeat
end if
end repeat
set text item delimiters to ""
set ts to (text ti thru -1 of s) as text
--> ABC6DE7
set s to "12345ABC6DE7"
set text item delimiters to characters of "abcdefghijklmnopqrstuvwxyz"
text ((length of text item 1 of s) + 1) thru -1 of s
1 Like
If there is a non-letter, non-numeral in among the initial numerals, then it will still generate the same result, for example:
set s to "1•23#45ABC6DE7"
→ “ABC6DE7”
I managed to delete my reply somehow. You are correct. Add potential characters to taste.
set s to "7654321•23#45ABC6DE7"
set text item delimiters to characters of "abcdefghijklmnopqrstuvwxyz•#"
text ((length of text item 1 of s) + 1) thru -1 of s