- Joined
- Nov 25, 2008
- Messages
- 1,309
This simple library uses a hashtable to replace instances of a string (case insensitive) with another string given by a function. Yes, this is coded in plain old JASS. You'll have to integrate the globals into your map (for instance by replacing the hashtable with your own hashtable variable). This is designed to work well with any map that uses a hashtable for storing data. Looping over the string is done in a method to reduce the number of strings created to as low as possible.
JASS:
//===========================================================================
//
// [Snippet] String Replacement Library
//
// Author: Zeatherann
// Description: Allows replacement of words found within an opening and closing deliminator.
//
// Notes: The strings registered to functions with this system use StringHash and therefore are case insensitive.
//===========================================================================
//***************************************************************************
//*
//* Global Variables
//*
//***************************************************************************
globals
constant integer udg_FilterWordIndex =0 // This is the index to use in the hashtable to store registered words in.
hashtable udg_Hash =InitHashtable() // This is the hashtable to store registered words in.
string udg_FilterStringReturn ="" // This is the variable functions registered to words needs to set to act as a return value.
constant string udg_OpeningCharacter ="[" // This is the opening deliminator to signal a word's beginning (has to be a single character).
constant string udg_ClosingCharacter ="]" // This is the closing deliminator to signal a word's end (has to be a single character).
endglobals // NOTE: These can be set to the same thing and still function properly.
//***************************************************************************
//*
//* String Filter system
//*
//***************************************************************************
//====================================================================================================
// RegisterWord
// takes string Word - The string to register to the function.
// boolexpr Function - The function to call when the string is found.
// returns nothing
//
// This function registers a string to a function to call should that string (case-insensitive) be found within the deliminators udg_OpeningCharacter and udg_ClosingCharacter.
//====================================================================================================
function RegisterWord takes string Word,boolexpr Function returns nothing
local trigger FilterFunction=CreateTrigger()
call TriggerAddCondition(FilterFunction,Function)
call SaveTriggerHandle(udg_Hash,udg_FilterWordIndex,StringHash(Word),FilterFunction)
set FilterFunction=null
endfunction
//====================================================================================================
// FilterString
// takes string Source - The string to replace parts of.
//
// returns string: A new string with parts replaced from Source.
//
// This function is takes a string and returns a new string that has pieces of it replaced by looking up the registered words.
//
// NOTE: If a string found within deliminators doesn't match any registered strings then it will not be replaced and will appear in the returned string as it is in Source.
//====================================================================================================
function FilterString takes string Source returns string
local integer I=0
local integer Last=0
local integer Length=StringLength(Source)
local string Char
local boolean ParsingToken=false
local string Return=""
local trigger FilterFunction
loop
exitwhen I==Length
set Char=SubString(Source,I,I+1)
if(ParsingToken)then
if(Char==udg_ClosingCharacter)then
set FilterFunction=LoadTriggerHandle(udg_Hash,udg_FilterWordIndex,StringHash(SubString(Source,Last+1,I)))
if(FilterFunction!=null)then
call TriggerEvaluate(FilterFunction)
set Return=Return+udg_FilterStringReturn
else
set Return=Return+SubString(Source,Last,I+1)
endif
set ParsingToken=false
set Last=I+1
endif
elseif(Char==udg_OpeningCharacter)then
set ParsingToken=true
set Return=Return+SubString(Source,Last,I)
set Last=I
endif
set I=I+1
endloop
return Return+SubString(Source,Last,I)
endfunction
JASS:
//***************************************************************************
//*
//* Example Using the String Filter system
//*
//***************************************************************************
//====================================================================================================
// Registered words
//====================================================================================================
function Example_FilteredWord_Adjative takes nothing returns nothing
local integer I=GetRandomInt(0,3)
if(I==0)then
set udg_FilterStringReturn="quick"
elseif(I==1)then
set udg_FilterStringReturn="slow"
elseif(I==2)then
set udg_FilterStringReturn="fast"
else
set udg_FilterStringReturn="sluggish"
endif
endfunction
function Example_FilteredWord_Color takes nothing returns nothing
local integer I=GetRandomInt(0,3)
if(I==0)then
set udg_FilterStringReturn="brown"
elseif(I==1)then
set udg_FilterStringReturn="red"
elseif(I==2)then
set udg_FilterStringReturn="orange"
else
set udg_FilterStringReturn="white"
endif
endfunction
function Example_FilteredWord_Adjative2 takes nothing returns nothing
local integer I=GetRandomInt(0,3)
if(I==0)then
set udg_FilterStringReturn="lazy"
elseif(I==1)then
set udg_FilterStringReturn="barking"
elseif(I==2)then
set udg_FilterStringReturn="sleeping"
else
set udg_FilterStringReturn="eating"
endif
endfunction
//====================================================================================================
// Register the example words
//====================================================================================================
function RegisterExamples takes nothing returns nothing
call RegisterWord("speed",Filter(function Example_FilteredWord_Adjative))
call RegisterWord("color",Filter(function Example_FilteredWord_Color))
call RegisterWord("action",Filter(function Example_FilteredWord_Adjative2))
endfunction
//====================================================================================================
// Test the example
//====================================================================================================
function Test_Example_Filtering takes nothing returns nothing
call BJDebugMsg(FilterString("The [speed] [color] fox jumped over the [action] dog.",0))
// Possible output: "The quick brown fox jumped over the lazy dog."
endfunction
Editions
- Prefixed all three global variables with 'udg_'.
- Added a tad more documentation.
- Added two new configurable options: udg_OpeningCharacter and udg_ClosingCharacter which determine the opening and closing deliminators. Also added more documentation and changed presentation a bit more.
- Added support for recursive parsing, with the number of recursions controlled via a second argument.
Last edited: