Core Function GSub
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