|
<< Click to Display Table of Contents >> Navigation: 3. Script Language > String commands > String Manipulation |
Intention
The `GFS.` command provides a powerful and flexible mechanism to process strings by selectively keeping or removing characters. It operates based on a sequence of single-character `prototypes` that define actions like building a character set, filtering the string based on that set, or performing immediate cleanup actions. Its strength lies in chaining multiple simple operations to achieve complex string manipulations.
Syntax
GFS.P1|P2[|P3][|P4]
The command takes between 2 and 4 parameters separated by the pipe symbol (`|`).
Parameter Forms:
-GFS.P1|P2(2 Parameters)- P1: Prototypes to execute.- P2: Input string source (`$$VAR` or `$tos$`).- Filter Set: Starts empty.- Output: Default (in-place modification if P2 is `$$VAR`, or `$tos$` if P2 is `$tos$`).
-GFS.P1|P2|P3(3 Parameters)- P1: Prototypes.- P2: Input string source.- P3: Initial Filter Set (`$$VAR` or literal string).- Output: Default (in-place or `$tos$`).
-GFS.P1|P2|P3|P4(4 Parameters)- P1: Prototypes.- P2: Input string source.- P3: Initial Filter Set.- P4: Output destination (`$$VAR` or `$tos$`).
-GFS.P1|P2||P4(4 Parameters with Empty P3)- P1: Prototypes.- P2: Input string source.- P3: Explicitly empty (use `||`). Filter Set starts empty.- P4: Output destination.Use this form when you need to specify an output (P4) but do not want to provide an initial filter set (P3).
Parameters Details
Param |
Type |
Description |
P1 |
Prototypes (String) |
Required. A string containing one or more single-character codes defining the operations to perform. Processed strictly left-to-right. See Prototypes section below. Example: "dz", "opmy", "cuz" |
P2 |
Input (Variable or `$tos$`) |
Required. The source string to be filtered.$$VAR: Use the content of the specified variable (must be `$$` followed by exactly 3 chars, e.g., `$$SRC`).$tos$: Use the string from the Top Of Stack. The string is consumed (popped). |
P3 |
Filter Set Initializer (Variable or String) |
Optional. Initializes the internal filter character set *before* processing P1 prototypes.$$VAR: Use the content of the variable (e.g., `$$FLT`)."LiteralString" or LiteralString: Use the literal string (e.g., `"AEIOU"` or `AEIOU`). Quoting may be safer if the literal contains spaces or special characters.If omitted, the filter set starts empty (unless P1 starts with `c` or `e`).Use `||` as a placeholder if P4 is needed but P3 should be empty. |
P4 |
Output (Variable or `$tos$`) |
Optional. Specifies where to store the final filtered string.$$VAR: Store the result in the variable (e.g., `$$RES`), overwriting its previous content.$tos$: Push the result onto the Top Of Stack.Default Behavior:If P2 (`Input`) is $tos$ and P4 is omitted, the result is pushed to $tos$.If P2 (`Input`) is $$VAR and P4 is omitted, $$VAR is updated in-place with the result. |
Prototypes (Parameter P1)
Prototypes are single characters defining actions. They operate sequentially on the input string (P2) and/or an internal 'filter character set'. The order is critical.
1. Filter Set Builders (Add Characters)
These prototypes append characters to the current internal filter set. This set is then used by the Filtering Actions (`x`, `y`, `z`).
Proto |
Action / Characters Added |
Mini Example (Effect on Filter Set) |
b |
Add uppercase English letters:ABCDEFGHIJKLMNOPQRSTUVWXYZ |
' Add A-Z to set GFS.bq|$tos$ ' q pushes set PRT.$tos$ ' Prints "ABC...XYZ" |
c |
Add custom characters from TOS: Takes a string from TOS and appends it to the filter set. (Ensure string is on stack *before* GFS executes). |
' Add "XYZ" from stack to set VAR.$$TMP=XYZ PUV.$$TMP GFS.cq|$tos$ ' q pushes set PRT.$tos$ ' Prints "XYZ" |
d |
Add decimal digits:0123456789 |
' Add 0-9 to set GFS.dq|$tos$ ' q pushes set PRT.$tos$ ' Prints "0123456789" |
f |
Add floating-point characters:0123456789. |
' Add digits and dot to set GFS.fq|$tos$ ' q pushes set PRT.$tos$ ' Prints "0123456789." |
g |
Add German umlauts and sz:äöüßÄÜÖß |
' Add German chars to set GFS.gq|$tos$ ' q pushes set PRT.$tos$ ' Prints "äöüßÄÜÖß" |
h |
Add hexadecimal characters:aAbBcCdDeEfF0123456789 |
' Add HEX chars to set GFS.hq|$tos$ ' q pushes set PRT.$tos$ ' Prints "aAbB...F01...9" |
i |
Add mathematical symbols:E.,()<>+-/\*^ |
' Add math symbols to set GFS.iq|$tos$ ' q pushes set PRT.$tos$ ' Prints "E.,()..." |
j |
Add grammatical symbols:!?.,;-() |
' Add punctuation to set GFS.jq|$tos$ ' q pushes set PRT.$tos$ ' Prints "!?.,;-()" |
k |
Add English letters (upper & lower):abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ |
' Add a-z and A-Z to set GFS.kq|$tos$ ' q pushes set PRT.$tos$ ' Prints "abc...xyzABC...XYZ" |
l |
Add German letters (English + German):abcdefghijklmnopqrstuvwxyzäöüABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜß |
' Add German letters to set GFS.lq|$tos$ ' q pushes set PRT.$tos$ ' Prints "abc...üABC...ß" |
m |
Add common valid filename characters (excludes `\` and `:`):abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZüöäÜÖÄß[]{}@.1234567890_-;:+#§%&()=! |
' Add filename chars to set GFS.mq|$tos$ ' q pushes set PRT.$tos$ ' Prints the long set above' |
n |
Add path separator characters::\ |
' Add path separators to set GFS.nq|$tos$ ' q pushes set PRT.$tos$ ' Prints ":\" |
s |
Add lowercase English letters:abcdefghijklmnopqrstuvwxyz |
' Add a-z to set GFS.sq|$tos$ ' q pushes set PRT.$tos$ ' Prints "abc...xyz" |
t |
Add time-related characters::0123456789 |
' Add time chars to set GFS.tq|$tos$ ' q pushes set PRT.$tos$ ' Prints ":0123456789" |
2. Filter Set Initializer (Replace Characters)
This prototype replaces the entire current filter set.
Proto |
Action / Characters Set |
Mini Example (Effect on Filter Set) |
e |
Set filter set to allowed email prefix characters:!#$%&'*+-/=?^_`.{|}~.Warning: Replaces any existing filter set characters. |
' Init set with digits, then replace GFS.d|$tos$ ' Set has "0123456789" GFS.eq|$tos$ ' Set now REPLACED, q pushes PRT.$tos$ ' Prints "!#$%&..." |
3. Filter Set Control
Proto |
Action |
Mini Example (Effect on Filter Set) |
u |
Clear/empty the internal filter character set. |
' Init set with digits, then clear GFS.d|$tos$ ' Set has "0123456789" GFS.uq|$tos$ ' Set now EMPTY, q pushes PRT.$tos$ ' Prints "" (empty string) |
4. Filtering Actions (Using Filter Set)
These prototypes modify the input string based on the *current* state of the internal filter character set when they are encountered.
Proto |
Action on Input String |
Mini Example (Effect on String) |
x |
Remove the exact sequence of characters matching the current filter set. (Like `REMOVE$`, not `ANY`) |
' Remove exact match "123" VAR.$$SRC=ABC123DEF123 VAR.$$FLT=123 GFS.x|$$SRC|$$FLT PRT.$$SRC ' Prints "ABCDEF123" |
y |
Remove all individual characters that are present in the current filter set (like `REMOVE$, ANY`). |
' Remove any of '1', '2', '3' VAR.$$SRC=A1B2C3D1E2F3 VAR.$$FLT=123 GFS.y|$$SRC|$$FLT PRT.$$SRC ' Prints "ABCDEF" |
z |
Keep only those individual characters that are present in the current filter set (like `RETAIN$, ANY`). Remove all others. |
' Keep only '1', '2', '3' VAR.$$SRC=A1B2C3D1E2F3 VAR.$$FLT=123 GFS.z|$$SRC|$$FLT PRT.$$SRC ' Prints "123123" |
5. Immediate String Actions
These prototypes modify the input string directly when encountered, independent of the current filter character set.
Proto |
Action on Input String |
Mini Example (Effect on String) |
o |
Remove ASCII control characters (codes 0 through 31). E.g., removes CR (13), LF (10), TAB (9). |
' Remove Line Feed (CHR(10)) VAR.$$SRC=Line1$lf$Line2 GFS.o|$$SRC PRT.$$SRC ' Prints "Line1Line2" |
p |
Replace non-breaking spaces (ASCII 160, often from web pages) with regular spaces (ASCII 32). |
' Replace ASCII 160 space VAR.$$SRC=Hello$xA0$World GFS.p|$$SRC PRT.$$SRC ' Prints "Hello World" |
v |
Apply specialized filter for valid **Path names**. Retains characters from the set defined by `$S_AX_Path` (combines `m` and `n` sets) and replaces ASCII 160 with space. It does *not* remove control chars or trim spaces like `w`. |
' Keep valid path chars VAR.$$SRC=C:\My*Dir?\Path.txt$xA0$ GFS.v|$$SRC PRT.$$SRC ' Prints "C:\MyDir\Path.txt " |
w |
Apply specialized filter for valid **File names**. Retains characters from `$S_AX_File` (`m` set), replaces LF/CR/ASCII 160 with spaces, replaces double spaces with single, and trims leading/trailing spaces (using `VBT.`). |
' Clean up a filename VAR.$$SRC= My*File?\r\nName.txt$xA0$ GFS.w|$$SRC PRT.$$SRC ' Prints "MyFileName.txt" |
6. Stack Operations
These allow interaction with the SPR-Script stack (TOS - Top Of Stack).
Proto |
Action |
Mini Example |
q |
Push the current internal filter set onto TOS. |
' Get current filter set onto stack GFS.dq|$tos$ ' d adds digits, q pushes PRT.$tos$ ' Prints "0123456789" |
r |
Push the current state of the input string being processed onto TOS. |
' Get intermediate string state VAR.$$SRC=A1B2 ' o removes nothing, r pushes string GFS.or|$$SRC PRT.$tos$ ' Prints "A1B2" |
7. Special Option: Binary Variable Resolution
Prototype 'a'
-Action: Use 'binary' variable resolution for the Input (P2) if P2 is a variable (`$$VAR`).
-Purpose: Prevents the `GFS.` command from further interpreting the content of the input variable P2. Normally, if `$$SRC` contained text like `$DATE$`, SPR-Script might expand `$DATE$` before `GFS.` processes the string. Using prototype `a` ensures `GFS.` operates on the literal content of `$$SRC` (e.g., the string "Filename is $DATE$.log") without expanding system variables or nested `$$VAR` variables within it.
-When to use: Use this typically only if your input variable (P2) contains text that *looks like* a system variable or another `$$VAR`, but you need `GFS.` to treat that text literally during filtering.
' Example (Conceptual)
VAR.$$SRC=Value is $$VAL ' $$SRC contains literal "$$VAL"
VAR.$$VAL=123
VAR.$$TMP=
' Using 'a': Process the literal content of $$SRC
' a: Use binary resolution for P2 ($$SRC)
' s: Add lowercase letters 'a-z' to filter set
' z: Keep only chars in filter set (only letters)
GFS.asz|$$SRC||$$TMP ' Use P4 for output to preserve $$SRC
PRT.Original SRC: $$SRC ' Prints "Value is $$VAL"
PRT.Filtered TMP: $$TMP ' Prints "alues" (keeps letters from literal "$$VAL")
' Without 'a': Expansion might happen first (depends on engine details)
' GFS.sz|$$SRC||$$TMP ' Might process "Value is 123" -> "alues"
' The 'a' ensures consistent handling of literal variable content.
ENR.
Execution Flow and Order Dependency
CRITICAL: Prototypes in P1 are executed strictly in the order they appear, from left to right. This sequential processing is fundamental to how `GFS.` works.
1. The input string is taken from P2 (`$$VAR` or `$tos$`).
2. The internal filter character set is initialized (either empty or from P3).
3. Each prototype in P1 is processed in sequence:
-Filter Set Builders/Initializer/Control (`b, c, d, e, f, g, h, i, j, k, l, m, n, s, t, u`) modify the internal filter set.
-Filtering Actions (`x, y, z`) use the filter set *as it exists at that exact moment* to modify the input string.
-Immediate Actions (`o, p, v, w`) modify the input string directly, regardless of the filter set state.
-Stack Operations (`q, r`) push the current state of the filter set or input string to TOS.
4. After all prototypes in P1 are processed, the final modified string is placed in the output destination (P4, in-place P2, or `$tos$`).
Consequence: You MUST build the filter set (e.g., using `d`, `s`, `c`, or P3) *before* applying a filter action (`x`, `y`, `z`) that relies on it.
' CORRECT: Build set (d), then filter (z)
VAR.$$SRC=ABC123DEF
GFS.dz|$$SRC
PRT.$$SRC ' Output: "123"
' INCORRECT: Filter (z) with empty set, then build (d)
VAR.$$SRC=ABC123DEF
GFS.zd|$$SRC
PRT.$$SRC ' Output: "" (empty string - z used an empty filter)
Comprehensive Examples
Example 1: Keep Only Digits (Basic)
' Goal: Extract numbers from a string
VAR.$$SRC="Order ID: 987-XYZ-654"
' d: Add digits '0'-'9' to filter set
' z: Keep only characters found in the filter set
GFS.dz|$$SRC ' Output to $$SRC (in-place)
PRT.Digits: $$SRC
' Output: Digits: 987654
ENR.
Example 2: Remove Punctuation (Using P4 for Output)
' Goal: Clean up text by removing common punctuation
VAR.$$TXT="Hello, world! How are you?"
' j: Add punctuation '!?.,;-()' to filter set
' y: Remove any characters found in the filter set
GFS.jy|$$TXT|$$RES ' Input $$TXT, Output to $$RES (P4)
PRT.Original: $$TXT
PRT.Cleaned: $$RES
' Output:
' Original: Hello, world! How are you?
' Cleaned: Hello world How are you
ENR.
Example 3: Input/Output via Stack ($tos$)
' Goal: Keep only Hex characters from string on stack
VAR.$$SRC="Value is 0xFF but not 0xGG"
PUV.$$SRC ' Push source string onto stack
' h: Add hex chars 'a-fA-F0-9' to filter set
' z: Keep only chars in filter set
' Input P2 is $tos$, Output P4 is omitted -> defaults to $tos$
GFS.hz|$tos$
' Result is now on the stack
PRT.Hex Chars: $tos$
' Output: Hex Chars: aeFFaeF09
ENR.
Example 4: Using Initial Filter Set (P3 Literal)
' Goal: Remove specific custom characters AND digits
VAR.$$SRC="Data [123] ~ Remove these ~ (456)"
' P3 ("[]~()") initializes the filter set
' d: Add digits '0'-'9' to the filter set -> "[]~()0123456789"
' y: Remove any char found in the combined filter set
GFS.dy|$$SRC|"[]~()"|$$RES ' Use literal for P3
PRT.Result: $$RES
' Output: Result: Data Remove these
ENR.
Example 5: Using Stack for Filter Chars (Prototype 'c')
' Goal: Remove vowels from a string
VAR.$$SRC="This Is An Example String"
VAR.$$VOW="aeiouAEIOU" ' Vowels to remove
PUV.$$VOW ' Push vowels onto stack BEFORE GFS call
' c: Add string from TOS ($$VOW) to filter set
' y: Remove characters in the filter set
GFS.cy|$$SRC
PRT.No Vowels: $$SRC
' Output: No Vowels: Ths s n Exmpl Strng
ENR.
Example 6: Combining Immediate Actions and Filter Actions
' Goal: Clean web data - remove control chars, fix spaces, keep only letters/numbers
VAR.$$SRC=" Product: Widget$xA0;100\r\nCode:\tABC-123 "
' o: Immediately remove control chars (\r, \n, \t -> ASCII 13, 10, 9)
' p: Immediately replace non-breaking space (ASCII 160) with space (32)
' k: Add letters 'a-zA-Z' to filter set
' d: Add digits '0-9' to filter set
' z: Keep only characters from the filter set (letters and digits)
GFS.opkdz|$$SRC
PRT.Cleaned: $$SRC
' Output: Cleaned: ProductWidget100CodeABC123
' Note: Spaces and hyphen removed by 'z' because not added by k or d.
ENR.
Example 7: Using 'u' to Clear Filter Set Mid-Process
' Goal: Remove letters, then keep only digits
VAR.$$SRC="Part: ABC-123 / Section: 456"
' k: Add letters 'a-zA-Z' to filter set
' y: Remove letters from the string -> "Part: --123 / Section: 456"
' u: Clear the filter set. It's now empty.
' d: Add digits '0-9' to the filter set. Set is now "0123456789".
' z: Keep only digits from the modified string.
GFS.kyudz|$$SRC
PRT.Result: $$SRC
' Output: Result: 123456
ENR.
Example 8: Creating a Valid Filename (Using 'm' and 'z')
' Goal: Convert an arbitrary string to a safe filename
VAR.$$SRC="My Document / Chapter 2: \"The End\"?.txt"
' m: Add valid filename characters to filter set (excludes \, :, etc.)
' z: Keep only characters in the filter set
GFS.mz|$$SRC
PRT.Filename: $$SRC
' Output: Filename: My Document Chapter 2 The End.txt
' Note: Still contains spaces. Use 'w' for more aggressive cleaning.
ENR.
Example 9: Advanced Filename Cleaning (Using 'w')
' Goal: Aggressively clean a string for use as a filename
VAR.$$SRC=" My Document / Chapter 2: \"The End\"?\r\n.txt "
' w: Apply specialized filename filter (removes invalid chars, CR/LF, trims, etc.)
GFS.w|$$SRC
PRT.Filename: $$SRC
' Output: Filename: My Document Chapter 2 The End.txt
ENR.
Example 10: Using 'q' and 'r' for Debugging
' Goal: Inspect filter set and string state during processing
VAR.$$SRC=A1 B2 C3
' d: add digits; q: push filter set; y: remove digits; r: push string state
GFS.dqyr|$$SRC
' Stack now contains (from top): "A B C ", "0123456789"
PRT.String State After Y: $tos$
PRT.Filter Set Before Y: $tos$
' Output:
' String State After Y: A B C
' Filter Set Before Y: 0123456789
ENR.
Example 11: Output to P4 without Initial Filter (Empty P3)
' Goal: Keep only digits, output to $$RES, no initial filter
VAR.$$SRC="Value: 123"
' d: Add digits to filter set (starts empty)
' z: Keep only digits
' P3 is empty (||), P4 is $$RES
GFS.dz|$$SRC||$$RES
PRT.Original: $$SRC
PRT.Result: $$RES
' Output:
' Original: Value: 123
' Result: 123
ENR.
Example 12: Difference between 'x', 'y', 'z'
VAR.$$SRC=--ABC--ABC--
VAR.$$FLT=ABC
' Using x: Remove exact match "ABC"
VAR.$$TMP=$$SRC
GFS.x|$$TMP|$$FLT
PRT.Result 'x': $$TMP ' Output: Result 'x': ----ABC--
' Using y: Remove ANY of 'A', 'B', 'C'
VAR.$$TMP=$$SRC
GFS.y|$$TMP|$$FLT
PRT.Result 'y': $$TMP ' Output: Result 'y': ------
' Using z: Keep ONLY 'A', 'B', 'C'
VAR.$$TMP=$$SRC
GFS.z|$$TMP|$$FLT
PRT.Result 'z': $$TMP ' Output: Result 'z': ABCABC
ENR.
Remarks
·The order of prototypes in P1 is the most critical aspect of using `GFS.`. Plan the sequence carefully: build the set, then apply actions.
·Remember the difference between Filter Actions (`x, y, z` which use the set) and Immediate Actions (`o, p, v, w` which don't).
·Use `u` (clear filter) strategically if you need to perform multiple, distinct filtering operations within a single `GFS.` command.
·For simple replacements, `RPL.` might be more straightforward. `GFS.` excels at complex, multi-step filtering based on character sets.
·When using the `c` prototype, ensure the filter string is pushed onto the stack (`PUV.`) *before* the `GFS.` command.
·The `a` prototype is mainly for edge cases where input variable content might be misinterpreted as system or nested variables.
·Prototypes `v` and `w` are convenient shortcuts for common path/filename cleaning but offer less control than building the steps manually (e.g., using `o`, `p`, `m`, `n`, `z`, and maybe `VBT.`).
·Always ensure variable names used (e.g., `$$SRC`, `$$RES`) conform to the `$$` + 3 characters rule.
·End scripts with `ENR.` or `END.` as appropriate.
See also:
• GPS. - Keep only given characters
• GNS. - Filter out given characters
• VBT. - Variable Both Sides Trim
• Variable Commands (VAR., VAB., etc.)
• Stack Operations (PUV., $tos$)