Page 1 of 1

Newbie: Trim?

Posted: Fri Mar 23, 2007 5:53 am
by kpeters
Just snooped around on my first day with Rev and could not find a trim (string) function - what does one use?

TIA
Kai

Posted: Fri Mar 23, 2007 6:35 am
by Janschenkel
Hi Kai,

There are two approaches: you either use Revolution's chunking abilities, or write a small function to fullfill your needs.
Approach 1: Revolution chunks

Code: Select all

on mouseUp
  put "  It's fun to be a lunatic!   " into tOriginalText
  put word 1 to -1 of tOriginalText into tTtrimmedText
  answer tOriginalText & return & tTrimmedText
end mouseUp
Approach 2: Custom function

Code: Select all

on mouseUp
  put "  It's fun to be a lunatic!   " into tOriginalText
  put Trim(tOriginalText) into tTtrimmedText
  answer tOriginalText & return & tTrimmedText
end mouseUp

function Trim pText
  return word 1 to -1 of pText
end Trim
As you can see, the custom function uses Revolution's chunking abilities to get its work done - but wrapping it in custom functions like this will ease your transition from other programming languages. Not to mention it will allow you to easily enhance the custom function in a single place.

Here is an alternate Trim function that uses optional parameters to determine which ends of the string it has to trim, as well as a list of characters that should be trimmed.

Code: Select all

function Trim pText, pWhichSides, pWhichChars
  -- first ensure the optional parameters have meaningful values
  if pWhichSides is empty then put "all" into pWhichSides
  if pWhichChars is empty then put space into pWhichChars
  -- then trim characters from left and/or right end of the string
  if pWhichSides is among the items of "all,left" then
    repeat while char 1 of pText is in pWhichChars
      delete char 1 of pText
    end repeat
  end if
  if pWhichSides is among the items of "all,right" then
    repeat while char -1 of pText is in pWhichChars
      delete char -1 of pText
    end repeat
  end if
  return pText
end Trim
Hope this helped,

Jan Schenkel.

Posted: Fri Mar 23, 2007 6:12 pm
by kpeters
Thanks so much for your elaborate reply, Jan!

Where do you store your libray functions? In a "library stack" of some sort?
If so, is that a regular stack file or can I create plain text files containing source code and then include/import them?


TIA,
Kai

Posted: Fri Mar 23, 2007 7:08 pm
by Janschenkel
Hi Kai,

A library stack is a stack that is loaded as a library by means of the 'start using' command.

Code: Select all

if "MyLibraryStack" is not among the lines of the stacksInUse then
  start using stack "MyLibraryStack"
end if
This can be a substack of your project stack, or it can be a mainstack by itself. The advantage of making it a substack is that you'll never lose it. The advantage of putting it in a mainstack of its own, is that you can reuse it among multiple projects.

If you chose to save it as its own mainstack, then you'll want to make it easy for your project to find that stack.
Go to your project stack, open the Stack Inspector, use the option menu at the top to switch to the Stack Files panel, and then click the Folder icon to find your library stack.
By adding your library stack to the stack files property of your project stack, you can call the 'start using' command like above, without specifying the full path of the library stack.
As an added bonus, the standalone builder will automatically include a copy of the library when you create your standalone application.

Hope this helped,

Jan Schenkel.

Re: Newbie: Trim?

Posted: Sun Sep 01, 2013 3:33 pm
by Wild
A simple regular expression can accomplish familiar trim() functionality:

Code: Select all

function trim input
   if matchText(input, "^\s*+(\S*(?:\s+\S+)*+)\s*+$", captureGroup1) then
      return captureGroup1
   else
      return input
   end if
end trim
This regular expression matches:
  • ^ -- the beginning of the input;
  • \s*+ -- any leading whitespace (possessive for speed: prevent each whitespace character that has been matched from being relinquished);
  • ( -- start capturing any characters encountered from now on (because we know the cursor in the input now points to the first non-whitespace character or the end of the input):
    • \S* -- any contiguous non-whitespace characters (ie the first "word", symbol, figure, etc.);
    • (?: -- start a group (for iterative reasons) but don't start an additional record to capture characters;
      • \s+ -- one or more whitespace characters;
      • \S+ -- one or more non-whitespace characters (eg the second "word", symbol, figure, etc.)
    • ) -- stop the nested group;
    • *+ -- try to match the nested group as many times as possible (possessive) but it's still OK even if the nested group cannot even match once (which will be the case if the input contains only a single "word");
  • ) -- stop capturing characters: any characters captured will be written to variable "captureGroup1";
  • \s*+ -- any trailing whitespace (possessive for speed: backtrack the entire \s sequence if the next token fails to match);
  • $ -- the end of the input.
For example, with input " Joe Blogs ":
  • ^
  • \s*+ -- " "
  • (
    • \S* -- "Joe"
    • (?:
      • \s+ -- " "
      • \S+ -- "Blogs"
    • )
    • *+ -- there are no more words to find to this non-capturing group only matches once;
  • ) -- stop capturing characters: the substring "Joe Blogs" will be copied to variable "captureGroup1";
  • \s*+ -- " "
  • $
If you want more control, you can change the above function to use regular expression character classes:

Code: Select all

function trimEx input, trimLeft, trimRight, trimCharsLeft, trimCharsRight, trimCharsCaseSensitive
   if trimCharsCaseSensitive is empty then put True into trimCharsCaseSensitive -- because PCRE is case-sens by default
   if trimCharsLeft is empty then put "\s" into trimCharsLeft
   if trimCharsRight is empty then put trimCharsLeft into trimCharsRight
   if trimLeft is empty then put True into trimLeft
   if trimRight is empty then put True into trimRight
   if not trimLeft then put "" into trimCharsLeft
   if not trimRight then put "" into trimCharsRight
   if trimCharsLeft is "^" then put "\" before trimCharsLeft
   if trimCharsRight is "^" then put "\" before trimCharsRight
   put "[" & trimCharsLeft & "]" into ccPrologue
   if trimCharsRight begins with "^" then -- eg "^ab"
      put "[" & character 2 to -1 of trimCharsRight & "]" into ccContent -- eg "[ab]"
      put "[" & trimCharsRight & "]" into ccFiller -- eg "[^ab]"
   else -- eg "ab"
      put "[^" & trimCharsRight & "]" into ccContent -- eg "[^ab]"
      put "[" & trimCharsRight & "]" into ccFiller -- eg "[ab]"
   end if
   if ccPrologue is "[]" then put "" into ccPrologue
   if ccPrologue is "[^]" then put "." into ccPrologue
   if ccContent is "[]" then put "" into ccContent
   if ccContent is "[^]" then put "." into ccContent
   if ccFiller is "[]" then put "" into ccFiller
   if ccFiller is "[^]" then put "." into ccFiller
   put "^(?:" & ccPrologue & ")*+((?:" & ccContent & ")*(?:(?:" & ccFiller & ")+(?:" & ccContent & ")+)*+)(?:" & ccFiller & ")*+$" into trimRegEx
   if not trimCharsCaseSensitive then put "(?i)" before trimRegEx
   if matchText(input, trimRegEx, captureGroup1) then
      return captureGroup1
   else
      return input
   end if
end trimEx
eg:

Code: Select all

put trimEx("_  Joe Blogs   xy  ", True, True, " _", " xyz")
Joe Blogs

put trimEx("0.50000", False, True, " ", "0")
0.5