enumerateSubstringsInRange

foundation
asobjc

(Jonas Whale) #1

Bonjour !

How do we set the parameters for the following ?

set aString to current application's NSString's stringWithString:theString
aString's enumerateSubstringsInRange:anNSRange options:NSStringEnumerationOptions usingBlock:(missing value)

(Shane Stanley) #2

ASObjC doesn’t support blocks, so you can’t use that method, unfortunately.


(Jonas Whale) #3

Thank you, Shane.

Which method can I use to split a string in parts (words, paragraphs, etc.) ?


(Ed Stockly) #4
every word of myText

or

every paragraph of myText

or

use text item delimiters:

set AppleScript's text item delimiters to {" ", tab, return, ",", "."}

every text item of myText

(Jonas Whale) #5

@estockly

My question was about AppleScriptObjC.
I’m re-writing a large part of my scripts.

It’s a good way to learn the language.
But in some cases, the path is hard to find.

Thank you anyway.


(Jim Underwood) #6

Interesting perspective.

I see ASObjC as an extension to native AppleScript. I only use it when it enables new capability I need, or it is materially faster than AppleScript. Given the simple, but effective, commands that @estockly posted, I would always use them rather than ASObjC, unless there was a compelling reason to do so.

Others may see it differently, and that’s fine. It is good to have options. :smile:

Good luck with your ASObjC education. I hope you do great stuff with it, and then share some cool solutions with us. :wink:

@alldritt or @ShaneStanley, could we please have a forum Category or Tag for ASObjC? Thanks.


(Phil Stokes) #7

Space works well for words as in this example; you can use “\n” or “\r” for paragraphs.

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
use framework "Foundation"

property NSString : a reference to current application's NSString
property NSArray : a reference to current application's NSArray
set sourceString to "humpty dumpty sat on wall"

set aString to NSString's stringWithString:sourceString

set anArray to (aString's componentsSeparatedByString:" ") as list


(Shane Stanley) #8

For paragraphs, you can use-paragraphRangeForRange: or -getParagraphStart:end:contentsEnd:forRange:, but in most cases it’s more effort than it’s worth. There’s no alternative for words.

Your two main options are either drop back to plain AppleScript, or use the methods in my BridgePlus library/framework, which access -enumerateSubstringsInRange::: under the hood.


(Jonas Whale) #9

@JMichaelTX
You’re right! If AppleScriptObjC does not bring an advantage, why loose time in udpading all that?

@sphil
If you want to re-construct the string after splitting, componentsSeparatedByString is the perfect candidate because it keeps punctuation, hyphens and other goodies with words.
“Hello, word” will return the comma attached to the word.

@ShaneStanley
BridgePlus and words of won’t return exactly the same results if the string contains non alphanumeric characters.
To me, the best result is returned by BridgePlus: with a string like “< hello, word >” it will ignore “<>”.

:wink:


(Jonas Whale) #10

Just for fun:

use script "Text Factory"
use theLib : script "BridgePlus"

set a1 to {}
repeat with a0 from 33 to 255
	set end of a1 to character id a0
end repeat
set a1 to a1 as text

set a2 to theLib's wordsOfString:a1
set a3 to words of a1

-- a2 -> {"0123456789", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", "ª", "µ", "º", "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ", "ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö", "øùúûüýþÿ"}
-- a3 -> {"$", "+", "0123456789", "<", "=", ">", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "^", "`", "abcdefghijklmnopqrstuvwxyz", "|", "~", "¢", "£", "¤", "¥", "¦", "¨", "©", "ª", "¬­", "®", "¯", "°", "±", "²", "³", "´", "µ", "¸", "¹", "º", "¼", "½", "¾", "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ", "×", "ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö", "÷", "øùúûüýþÿ"}

(Shane Stanley) #11

You can also use character sets to fine-tune the definition of a word. For example:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set theString to current application's NSString's stringWithString:"hello, world"
set theWords to theString's componentsSeparatedByCharactersInSet:(current application's NSCharacterSet's alphanumericCharacterSet()'s invertedSet())
set theWords to theWords's filteredArrayUsingPredicate:(current application's NSPredicate's predicateWithFormat:"length > 0")

It’s not outrageously slow.


(Mark Alldritt) #12

There has been an asobjc tag for ages but its only been used 3 times.


(Jim Underwood) #13

While “asobjc” shows up in the tag list:

It is NOT available to me when I create a new topic:

Something is wrong in either the “tags” setup and/or in user permissions.
I’ve never seen this issue in the KM Forum (which is also a Discourse forum).


(Jim Underwood) #14

It is like any other tool: There are places where it is the best tool to use, and can offer great advantages. But not necessarily for every job. :wink:

Over the years I have seen many times where people become enamoured with a tool/technology/device and then insist on using it for all jobs.


(Jonas Whale) #15

@ShaneStanley

Is it possible to add some characters to the set?
Like apostrophe or non-breacking hyphen?

This because I want to keep words like “l’étude” or “cerf-volant” not splitted.

Otherwise, componentsSeparatedByString will be fine, added with some regex find & replace.

@JMichaelTX

:wink:


(Shane Stanley) #16

Sure:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set theString to current application's NSString's stringWithString:"hello, world-wide"
set theSet to (current application's NSMutableCharacterSet's alphanumericCharacterSet()'s invertedSet())
theSet's removeCharactersInString:"'’-"
set theWords to theString's componentsSeparatedByCharactersInSet:theSet
set theWords to theWords's filteredArrayUsingPredicate:(current application's NSPredicate's predicateWithFormat:"length > 0")

(Jonas Whale) #17

Merci beaucoup!

I’ll work on it tomorow but I couldn’t wait to say (one more time):
Thank you!

:wink: