replace the nth word in a string

Hi all,

I need some help with this script. I need it to find numbers in a string and replace them with a calculated other number. Somehow I can’t get it to work…

set theString to "Is this a test? This test has 12 words."
repeat with currentWord from 1 to (count words in theString)
	try
		set word currentWord of theString to (round (((word currentWord of theString) as number) / 4 * 3)) as string
	end try
end repeat

display dialog theString with icon 1 with title "test" buttons {"Ok"} default button "Ok"

I know the code in “try” doesn’t work but I don’t know how to get it right.

Say in words what you want to accomplish.

I apologize but you are on a wrong track : a number isn’t a word.
You must work with text items.


set theString to "Is this a test? This test has 12 words."
set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, space}
set theList to text items of theString

repeat with i from 1 to count of theList
	set anItem to item i of theList
	repeat with j from 1 to count of anItem
		if text j of anItem is not in "0123456789" then exit repeat
		anItem / 4 * 3
		# result as integer
		set item i of theList to result
	end repeat
end repeat
set theString to theList as text

set AppleScript's text item delimiters to oTIDs
theString

If you want the new value treated as an integer, just uncomment the instruction :

result as integer

Yvan KOENIG (VALLAURIS, France) samedi 12 janvier 2013 21:16:13

Hi Yvan,

thanks a lot, it works great. There is only one problem; if the number is preceded of followed by another character it does not work anymore. e.g. “Is this test number 55? Working on Project32.”
I have been experimenting with separating each item. Not really nice coding, but it works.

set theString to "This has 12 words. Or M43. Maybe 20"
set theList to characters of theString
set theString to ""
set theNumber to 0 as number
set aNumber to false

repeat with i from 1 to count of theList
	if item i of theList is in {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"} then
		if aNumber is false then
			set aNumber to true
			set theNumber to (item i of theList as number)
		else
			set theNumber to theNumber * 10
			set theNumber to theNumber + (item i of theList as number)
			if i = (count of theList) then set theString to theString & (round (theNumber / 4 * 3))
		end if
	else
		if aNumber is false then
			set theString to theString & item i of theList
		else
			set aNumber to false
			set theString to theString & (round (theNumber / 4 * 3)) & item i of theList
		end if
	end if
	
end repeat
display dialog theString

I apologize but I was unable to guess that the numeric component of a string like M43 was supposed to be edited by the script.

Here is a slightly edited script :


set theString to "This has 120 words. Or M43. Maybe 2013"
set theList to text items of theString
set theString to ""
set aNumber to false

repeat with i from 1 to count of theList
	if item i of theList is in "0123456789" then 
		if aNumber is false then
			set aNumber to true
			set theNumber to item i of theList
		else
			set theNumber to theNumber * 10 + (item i of theList)
			if i = (count of theList) then set theString to theString & (round (theNumber / 4 * 3))
		end if
	else
		if aNumber is false then
			set theString to theString & item i of theList
		else
			set aNumber to false
			set theString to theString & (round (theNumber / 4 * 3)) & item i of theList
		end if
	end if
	
end repeat
display dialog theString

As you may see,
(1) I’m not fond of «characters of»
(2) I removed the initialization of theNumber which was useless
(3) I edited the main test because there is no need to use a list in this one
(4) I grouped two instructions in a single one
(5) I removed several coercions which were duplicating automatic implicit ones.

Yvan KOENIG (VALLAURIS, France) dimanche 13 janvier 2013 14:37:45

Thanks, I’ll learn it someday…

the reason I put this

set theNumber to theNumber * 10
set theNumber to theNumber + (item i of theList as number)

in two lines is to make it more clear what I am doing, but thanks for the information and the quick responses!

regards,
Arvid

His code wasn’t so bad because you can do this:

4 * (word 2 of "2 8")

You can do calculations with words.

Anyway the actual problem is that AppleScript doesn’t have text functions other than getters for substrings. His code would work when you’re in applications like Quark because there are application that have those functions for text objects. Simplest code for me would be extracting all numbers from the text and do a simple string replace.

set theString to "This has 120 words. Or M43. Maybe 2013"
set numbersFromtheString to every paragraph of (do shell script "egrep -o '[0-9]+' <<< " & quoted form of theString & " | sort -u")


repeat with theNumber in numbersFromtheString
	set AppleScript's text item delimiters to theNumber
	set x to every text item of theString
	set AppleScript's text item delimiters to (round (theNumber / 4 * 3)) as text
	set theString to x as string
	set AppleScript's text item delimiters to ""
end repeat
display dialog theString