Core Function GSub

From Sputnik Wiki
Jump to: navigation, search
GSub( <string>, <pattern>, <repl>, <max> )

Contents

Description

Returns a copy of the string in which all occurrences of the pattern have been replaced by a replacement string (Or fills an array/callback function).

Parameters

string

The string to evaluate.

pattern

Go read the Patterns section on the Find( ) function to learn how to create and use patterns then come back here to put it to use on this function.

repl

Optional; Replacement

If repl is a String, then its value is used for replacement. The character % works as an escape character: any sequence in repl of the form %n, with n between 1 and 9, stands for the value of the n-th captured substring (see below). The sequence %0 stands for the whole match. The sequence %% stands for a single %.

If repl is an Array, then the array is queried for every match, using the first capture as the key; if the pattern specifies no captures, then the whole match is used as the key.

If repl is a Function, then this function is called every time a match occurs, with all captured substrings passed as arguments, in order; if the pattern specifies no captures, then the whole match is passed as a sole argument.

If repl is a Call to a function such as say(), then this function is called every time a match occurs, with all captured substrings passed as arguments, in order (after the arguments you place in the call if you type say("test") then you capture two groups they will come after the "test" when calling the function); if the pattern specifies no captures, then the whole match is passed as a sole argument.

Default: An empty string

max

Optional; Limits the maximum number of substitutions to occur.

For instance, when max is:

-1 = all occurrences of pattern is replaced (any negative value does this).
0 = nothing is replaced.
1 = only the first occurrence of pattern is replaced.

Return Value

Returns a string which is a copy of String in which all occurrences of the pattern have been replaced by a replacement string specified by repl, which may be a String, an Array, or a Function.

Remarks

This function is pretty much the same a the LUA String.GSub() however this one returns start position starting at 0 (LUA's starts at 1) and lowers the end position by 1, Also the Offset begins at 0 here where as in LUA it begins at 1.

This is because in Sputnik chars in a string start at 0 not 1.

In LUA GSub() also returns, as its second value, the total number of substitutions made.

However in Sputnik this second value is not returned since that would involve returning an ARRAY and that is something I don't want to do instead I want GSub() to return strings only.

You can however get the second value from GSub() from using the @GSubCount macro immediately after calling GSub().

@GSubCount

This function also sets the total number of substitutions made but it does not return it with called instead you must request this count yourself by calling the @GSubCount macro example:

say gsub("hello world", "(%w+)", "%1 %1");
say "Number of replacements: " . @GSubCount;
// Prints
// hello hello world world
// Number of replacements: 2

Note - This variable is created local scope and applies to you immediately like the regex @groups does so you must grab it right away since if you wait too long you risk losing it.

Did it really change it?

Replacing a with a?

say gsub("a", "a", "a");
say "Number of replacements: " . @GSubCount;
// Prints
// a
// Number of replacements: 1

This function actually counts replacing a value with the same text as a valid replacement.

In a sense, the @GSubCount is accurate if you count replacing "a" by "a" as a replacement.

Example

A basic example that also uses the @GSubCount

say gsub("hello world", "(%w+)", "%1 %1");
say "Number of replacements: " . @GSubCount;
// Prints
// hello hello world world
// Number of replacements: 2


say gsub("hello world", "%w+", "%0 %0", 1);
// Prints
// hello hello world


say gsub("hello world from Spuntik", "(%w+)%s*(%w+)", "%2 %1");
// Prints
// world hello Spuntik from


say gsub("hello Sputnik!", "(%a)", "%1-%1");
say "Count: " . @GSubCount;
// Prints
// h-he-el-ll-lo-o S-Sp-pu-ut-tn-ni-ik-k!
// Count: 12

Using gsub() to trim whitespace

my $s = "   		Hello    			";
say gsub($s, '^%s*(.-)%s*$', "%1");
say "Count: " . @GSubCount;
// Prints
// Hello
// Count: 1

Using a function as the replacement

// Find each word and uppercase it
my $string = 'lol is cat hehe, isnt it?';
say gsub($string, '(%w+)', function($s) { return uc($s); });
// Prints
// LOL IS CAT HEHE, ISNT IT?

Same as above but with condition

// Find each word and uppercase it
// but only if it contains a "t"
my $string = 'lol is cat hehe, isnt it?';
say gsub($string, '(%w+)', function($s) { return Contains($s, 't') ? uc($s) : null; });
// Prints
// lol is CAT hehe, ISNT IT?

Using a function as the replacement but note each capture becomes a new parameter in the function

my $string = 'lol is cat hehe, isnt it?';
say gsub($string, '(%w+) (%w+)', function($s, $t) { return "$t $s"; });
// Prints
// is lol hehe cat, it isnt?

Use gsub() a search + replace but allow for matching whole words only and not partial

my $source  = 'test testing this test of testicular footest testimation test';
my $find    = 'test';
my $replace = 'XXX';
// Replace any found match
say "Non-Whole Replace";
say ReplaceText($source, $find, $replace, false);
say "Whole Replace";
// Replace only whole matches (not something thats part of something else!)
say ReplaceText($source, $find, $replace, true);
// Prints:
// Non-Whole Replace
// XXX XXXing this XXX of XXXicular fooXXX XXXimation XXX
// Whole Replace
// XXX testing this XXX of testicular footest testimation XXX
 
function ReplaceText($source, $find, $replace, $wholeword)
{
	if( $wholeword )
		$find = '%f[%a]' . $find . '%f[%A]';
	return gsub($source, $find, $replace);
}

Fill an array with the captures

Global $results = array();
gsub("hello hi, again!", "(%a+)", function($w) { $results[] = $w; });
printr $results;
// Prints
// Array
// (
//     [0] => hello
//     [1] => hi
//     [2] => again
// )

It doesnt need to be a global array

my $results = array();
gsub("hello hi, again!", "(%a+)", function($w) { $results[] = $w; });
printr $results;
// Prints
// Array
// (
//     [0] => hello
//     [1] => hi
//     [2] => again
// )

If you provide an array with keys and values the keys will be checked against the captured matches and if its a match it will use the arrays value

Global $replacements = array( "name" => "T3Charmy", "code" => 1337 );
say gsub("Welcome #name, Your code for today is #code", "#(%a+)", $replacements);
// Prints
// Welcome T3Charmy, Your code for today is 1337

Of course if the given key is not found in the array it will use the captured match instead

Global $replacements = array( "name" => "T3Charmy", "code" => 1337 );
say gsub("Welcome #name, Code is #code and time is #time", "#(%a+)", $replacements);
// Prints
// Welcome T3Charmy, Code is 1337 and time is #time

Oh and it doesnt need to be a global array

my $replacements = array( "name" => "T3Charmy", "code" => 1337 );
say gsub("Welcome #name, Code is #code and time is #time", "#(%a+)", $replacements);
// Prints
// Welcome T3Charmy, Code is 1337 and time is #time

Replace #tags in a string with Sputnik global variables

Global $name = "Sputnik";
Global $status = "great";
 
my $string = '#name is #status, isnt it?';
say gsub($string, '#(%w+)', function($s) { return "{\$$s}"; });
// Prints
// Sputnik is great, isnt it?

Replace $tags in a string with Sputnik global variables

Global $name = "Sputnik";
Global $status = "great";
 
my $string = '$name is $status, isnt it?';
say gsub($string, '$(%w+)', function($s) { return "{\$$s}"; });
// Prints
// Sputnik is great, isnt it?

Replace #tags in a string with Sputnik local variables

my $name = "Sputnik";
my $status = "great";
 
my $string = '#name is #status, isnt it?';
say gsub($string, '#(%w+)', function($s) { return "{\$$s}"; });
// Prints
// Sputnik is great, isnt it?

Replace $tags in a string with Sputnik local variables

my $name = "Sputnik";
my $status = "great";
 
my $string = '$name is $status, isnt it?';
say gsub($string, '$(%w+)', function($s) { return "{\$$s}"; });
// Prints
// Sputnik is great, isnt it?

Count "/" chars in a path using the following idiom

my $path = "/many/nested/directories";
gsub($path, "/");
say "Number: " . @GSubCount;
// Prints
// Number: 3

Count number of vowels

gsub("the quick brown fox", "[aeiou]");
say "Number of vowels: " . @GSubCount;
// Prints
// Number of vowels: 5

A custom function to Split strings made with GSub()

// Create a function that can Split strings up
// when it finds the split pattern
function SplitStr( $string, $inSplitPattern, $outResults )
{
   my $outResults = array();
   my $theStart = 0;
   my List ( $theSplitStart, $theSplitEnd ) = find( $string, $inSplitPattern, $theStart );
   while($theSplitStart)
   {
      $outResults[] = sub( $string, $theStart, $theSplitStart-1 );
      $theStart = $theSplitEnd + 1;
      List ( $theSplitStart, $theSplitEnd ) = find( $string, $inSplitPattern, $theStart );
   }
   $outResults[] = sub( $string, $theStart );
   return $outResults;
}
 
// Print on each , delim
printr SplitStr("the,quickish,bown,fox,k", ',');
// Prints
// Array
// (
//     [0] => the
//     [1] => quickish
//     [2] => bown
//     [3] => fox
//     [4] => k
// )
// Print at each sequence of numbers
printr SplitStr("the111quickish22bown3333333fox444k", '%d+');
// Prints
// Array
// (
//     [0] => the
//     [1] => quickish
//     [2] => bown
//     [3] => fox
//     [4] => k
// )

Wrap text using GSub()

// Create a function to wrap text it uses the GSub() function
// with an embedded function to do the processing
Function textWrap( $str, $limit = 72, $indent = "", $indent1 = "" )
{
   my $here = 1 - strlen($indent1);
   return $indent1 . $str->>gsub( "(%s+)()(%S+)()",
      function ( $sp, $st, $word, $fi )
	  {
         if ( $fi - $here > $limit )
		 {
            $here = $st - strlen($indent);
            return "\n" . $indent . $word;
         }
      } );
}
// Create some text to wrap
my $initialText = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";
// Wrap it
my $wrappedText = textWrap( $initialText, 36, null, "    " );
// Print it
say $wrappedText;
// Prints
//     Lorem ipsum dolor sit amet,
// consetetur sadipscing elitr, sed
// diam nonumy eirmod tempor invidunt
// ut labore et dolore magna aliquyam
// erat, sed diam voluptua. At vero eos
// et accusam et justo duo dolores et
// ea rebum. Stet clita kasd gubergren,
// no sea takimata sanctus est Lorem
// ipsum dolor sit amet.

Format as “Title Case” in this example the function name is used as the replacement instead of function() {} it is a shorthand for it

// A function to Title Case
Function TitleCase( $first, $rest )
{
	return uc($first) . lc($rest);
}
// Set a name to try change into Title Case
my $Name = "Obi-waN kEnObi";
// Use the TitleCase() function with gsub()
// Notice no arguments are given to the function?
// gsub() will automatically give it all the captured
// groups you only need your function definition to 
// handle them not the call to it
$Name = gsub( $Name, "(%a)([%w_']*)", titleCase() );
// Print the result
say $Name;
// Prints
// Obi-Wan Kenobi
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox