[Include] [INC] strlib v1.3 - Simple string modification (Update: 21/10/09)
#1

strlib - v1.3

Missed PHP's excellent string modification functions? Yeah, but that was because it was easy. I decided to create a string include that is stand alone - each function works in or out of the include - no dependencies apart from the core supplied files. But why? Because I can, and I wanted it. I wanted to be able to effectively cut strings up into pieces, remove stupid white space from lines in files, remove certain characters from certain words for a certain effect, or even replace whole words if you want to. You can do what ever you want, within reason, with this.

Function tests prove efficiency, albeit outdated efficiency!

Function list
Remember that this is the function list that you need to know, the full documentation is in the source code.
pawn Code:
/*
    str_replace:
        Case sensitive string replace

    Arguments:
        sSearch[]    String to search for
        sReplace[]   String to replace with
        sSubject[]   Original string
        (op) &iCount  How many times 'sSearch' has been replaced.

    Returns:
        Replaced string.
*/

native str_replace(sSearch[], sReplace[], const sSubject[], &iCount = 0)
pawn Code:
/*
    str_ireplace:
        Case insensitive string replace

    Arguments:
        sSearch[]    String to search for
        sReplace[]   String to replace with
        sSubject[]   Original string
        (op) &iCount  How many times 'sSearch' has been replaced.

    Returns:
        Replaced string.
*/

native str_ireplace(sSearch[], sReplace[], const sSubject[], &iCount = 0)
pawn Code:
/*
    str_pad:
        Pad a string with characters until the defined amount.

    Arguments:
        sSource[]     String input to pad.
        iPadLength    Pad to amount. If less than sSource, sSource is returned.
        (op) cPadChar  Character to use as padding.

    Returns:
        Padded string.
*/

native str_pad(const sSource[], iPadLength, cPadChar = ' ')
pawn Code:
/*
    str_repeat:
        Repeats a string 'iMultiplier' times.

    Arguments:
        sSource[]   String to be repeated
        iMultiplier Amount of times to be repeated

    Returns:
        Repeated string.
*/

native str_repeat(const sSource[], iMultiplier)
pawn Code:
/*
    str_rot13:
        Rotates alphabetical characters 13 characters along.

    Arguments:
        sSource[]   String to be rotated

    Returns:
        Rotated string.
*/

native str_rot13(const sSource[])
pawn Code:
/*
    strtr:
        Removes 'sRemove' from the string and replaces
        that character from 'sReplace'.

    Arguments:
        sSource[]   String to be transformed
        sRemove[]  Characters to be removed (must be in same order as below!)
        sReplace[]  Characters to be replaced (must be in same order as above!)

    Returns:
        Trimmed string.
*/

native strtr(const sSource[], sRemove[], sReplace[])
pawn Code:
/*
    substr:
        Gets a substring from a string.

    Arguments:
        sSource[]   String to be substring'd.
        iStart    Position for the start of substring.
        iLength    Position for the end of substring.
                (if negative, cells away from end)

    Returns:
        Substring.
*/

native substr(const sSource[], iStart, iLength = sizeof(sSource))
pawn Code:
/*
    trim:
        Removes whitespace, tabs, and new lines
        from the beginning and end of 'sSource'.

    Arguments:
        sSource[]   String to be trimmed

    Returns:
        Trimmed string.
*/

native trim(const sSource[])
pawn Code:
/*
    rtrim:
        Removes whitespace, tabs, and new lines
        from the end of 'sSource'.

    Arguments:
        sSource[]   String to be trimmed

    Returns:
        Trimmed string.
*/

native rtrim(const sSource[])
pawn Code:
/*
    ltrim:
        Removes whitespace, tabs, and new lines
        from the beginning of 'sSource'.

    Arguments:
        sSource[]   String to be trimmed

    Returns:
        Trimmed string.
*/

native ltrim(const sSource[])
pawn Code:
/*
    implode:
        Returns a string where the array has been stuck back together
        again.

    Arguments:
        aPieces[][]  The array to glue back together.
        sGlue     The string to use as the glue.

    Returns:
        The imploded string.
*/

native implode(const aPieces[][], const sGlue[] = " ")
pawn Code:
/*
    explode:
        Creates an array of values from 'sSource', where only the exact amount of
        values matching sizeof(aExplode) are returned.

    Arguments:
        aExplode[][] The exploded array
        sSource[]   Source string.
        sDelimiter  The string to use as the delimiter.

    Returns:
        Returns -1 on failure, otherwise success.
*/

native explode(aExplode[][], sSource[], sDelimiter[] = " ")
pawn Code:
/*
    explodea:
        Creates an array of values from 'sSource', where any overrun is stored in
        the final node.

    Arguments:
        aExplode[][] The exploded array
        sSource[]   Source string.
        sDelimiter  The string to use as the delimiter.

    Returns:
        Returns -1 on failure, otherwise success.
*/

native explodea(aExplode[][], sSource[], sDelimiter[] = " ")
pawn Code:
/*
    str_in_array:
        Checks if a string matches any of the strings in the array.

    Arguments:
        sNeedle[]   String that is being matched.
        aHaystack[][] Array with strings to be searched,

    Returns:
        Returns true on a match.
*/

native str_in_array(sNeedle[], aHaystack[][])
Download: http://files.typefish.co.uk/sa-mp/strlib.inc
-> No mirrors thanks.

Fancy documentation: http://docs.typefish.co.uk/samp/pawn/strlib/

Any problems, post in the topic. See ya!
Reply
#2

Hmm, I will definitely make use of this in the future.
Reply
#3

This is extremely useful, nice job!
Reply
#4

Alright, I have modified strtr so that you are able to remove characters all together. Check the first post for details.
Reply
#5

Good work.
Reply
#6

Nice work Westie
Reply
#7

Very useful, good job!
Reply
#8

cool
Reply
#9

Updated, added functions for exploding strings! Kaboom.
Reply
#10

Sorry I don't get what explode does, could you explain me? If it does what I think it does, I could use it :+
Reply
#11

It's like strtok, or like sscanf with the p<delimiter>.
https://sampwiki.blast.hk/wiki/Fast_Commands#Data_types
Reply
#12

...except it's a lot faster than strtok.

Testing explode()
My first test was to test the speeds of various functions to do with exploding strings. explode() and explodea() are both written by me, and they are very similar, except explodea() is slightly more complex. On the other hand, split() is a function found in GF-RP, and seeing as that is one of the most popular game modes (and the most hated, by me), I thought I should include it. Also, for fair comparison, I used ysi_explode(), this function was renamed from explode(), and this can be found in YSI.

Код:
explode(): 0860, explodea(): 0828, split(): 2187, ysi_explode(): 1922
explode(): 0766, explodea(): 0812, split(): 2156, ysi_explode(): 1875
explode(): 0735, explodea(): 0797, split(): 2187, ysi_explode(): 1875
explode(): 0719, explodea(): 0828, split(): 2172, ysi_explode(): 1859
explode(): 0735, explodea(): 0812, split(): 2891, ysi_explode(): 2531
As you can see, using explode() has a lot of savings. These new versions are even faster than the 'inefficient' previous core, which were miles faster than the other functions anyway.

Testing str_replace()
I used my str_replace() function, and compared it to the one that is in dUtils, as well as the one found from here (Dabombber):

Код:
str_replace(): 0266, dutils_strreplace(): 7125, dabombber_strreplace(): 0516
str_replace(): 0266, dutils_strreplace(): 6625, dabomber_strreplace(): 0484
str_replace(): 0266, dutils_strreplace(): 6328, dabomber_strreplace(): 0500
str_replace(): 0282, dutils_strreplace(): 6078, dabomber_strreplace(): 0515
str_replace(): 0266, dutils_strreplace(): 6703, dabomber_strreplace(): 0500
Reply
#13

for those wanting to replace split with explode you can do this to easily replace all instances of split with explode.

pawn Код:
#define explode_(%1,%2, explode(%2,%1
this is because the first two parameters for explode and split are backwards so the first parameter in split is the second parameter in explode, vice versa.

^ using that you will have to change the delimiter to a string aswell, so ',' to ",".

or you could possibly use

pawn Код:
#define explode_(%1,%2, chr_explode(%2,%1
and not have to change the delimiter to a string. But westie was talking of removing chr_explode.

so using that define you can find & replace all instances of split( with explode_(
Reply
#14

Quote:
Originally Posted by /^We(stie|z+[e|a
r)$/ ]
Testing str_replace()
I used my str_replace() function, and compared it to the one that is in dUtils, as well as the one found from here (Dabombber):

Код:
str_replace(): 0266, dutils_strreplace(): 7125, dabombber_strreplace(): 0516
str_replace(): 0266, dutils_strreplace(): 6625, dabomber_strreplace(): 0484
str_replace(): 0266, dutils_strreplace(): 6328, dabomber_strreplace(): 0500
str_replace(): 0282, dutils_strreplace(): 6078, dabomber_strreplace(): 0515
str_replace(): 0266, dutils_strreplace(): 6703, dabomber_strreplace(): 0500
Just out of curiosity, did you use strinsEx in both functions? Mine is a few times faster than yours if the native strins is used but it's possible to get buffer overflows. There's also a couple of bugs in yours

[code=pawn]str_replace("dog", "cat", "The quick brown fox jumps over the lazy dog")[/code]

doesn't replace and

[code=pawn]strins(sReturn, sReplace, iIndex, iLengthReplace);[/code]

should be

[code=pawn]strins(sReturn, sReplace, iIndex, sizeof(sReturn));[/code]

not that it really matters since strins doesn't seem to do any bounds checking
Reply
#15

Tanks
Reply
#16

Explode doesn't read the the last part of a string if the delimiter isn't at the end, for example

1|2|3|4

if you use explode to split those, it will only read 1, 2 and 3 but not 4.

Waiting for a fix for this.
Reply
#17

To fix up the bug with explode, I added a temporary solution.

pawn Код:
/*
    explode:
        Creates an array of values from 'sSource', where only the exact amount of
        values matching sizeof(aExplode) are returned.

    Arguments:
        aExplode[][]  The exploded array
        sSource[]    Source string.
        sDelimiter   The string to use as the delimiter.
        iVertices    Vertices of aExplode, detected automatically.
        iLength     Length of a string in aExplode, detected automatically.

    Returns:
        Returns -1 on failure, otherwise success.
*/

stock explode(aExplode[][], sSource[], const sDelimiter[] = " ", iVertices = sizeof aExplode, iLength = sizeof aExplode[])
{
    strins(sSource, sDelimiter, strlen(sSource), 28);
    new
        iNode,
        iPointer,
        iPrevious = -1,
        iDelimiter = strlen(sDelimiter);
   
    while(iNode < iVertices)
    {
        iPointer = strfind(sSource, sDelimiter, false, iPointer);

        if(iPointer == -1)
        {
            strmid(aExplode[iNode], sSource, iPrevious, iLength, iLength);
            break;
        }
        else
        {
            strmid(aExplode[iNode], sSource, iPrevious, iPointer, iLength);
        }
       
        iPrevious = (iPointer += iDelimiter);
        ++iNode;
    }
   
    return iPrevious;
}
Reply
#18

Quote:
Originally Posted by Y_Leѕѕ
pawn Код:
/*
    (DEPRECIATED) chr_explode:
        Creates an array of values from 'sSource', where only the exact amount of
        values matching sizeof(aExplode) are returned.
*/
pawn-lang.pdf is a wonderful thing:

Quote:
#pragma deprecated value
The subsequent symbol is flagged as “deprecated”. If a script uses it, the parser issues a warning.

However if this is a first release and that function is already deprecated - why include it in the first place? Also, there's a difference between "depreciated", which you used and "deprecated", which is the correct word here.
I forgot about that directive. I haven't used it in such a long time, it escaped my mind. And it is the second release, but I decided to keep it in there. Because I use the word 'depreciation' a lot when talking about other words, 'i' tends to creep into there. Bla bla. I'll go ahead and fix/optimise it now.

_________________________________________________

Quote:
Originally Posted by Dabombber
...
Sorry for the late reply to that particular post.

pawn Код:
main()
{
    print(str_replace("dog", "cat", "dog dog dog dog"));
    // Returns: cat cat cat dog
}
You're right, the last match doesn't get replaced. I fixed it with adding + 1 to a variable.
Reply
#19

Great work, I love the string functions in PHP, makes me miss how easy it is to format strings. Anyway, nice work .
Reply
#20

Updated! woo!
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)