D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 7146 - enhance strip* (implementation provided)
Summary: enhance strip* (implementation provided)
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: phobos (show other issues)
Version: D2
Hardware: Other All
: P2 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-12-21 00:50 UTC by pompei2
Modified: 2014-06-06 21:46 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description pompei2 2011-12-21 00:50:17 UTC
In some languages (e.g. python), the string "strip" function family accepts an optional parameter which specifies the set of characters one wants to strip. If not given, this is "whitespace". I think this is very useful and the D strip should support that too.

For example, I needed it when getting a char buffer filled by a C function and converting it to a string. Here is the implementation of these including unittests that you can just drop into the string.d file if you remove the import line. I would very much like to see this included in phobos - no copyright/whatever needed.




// Remove when integrating into std.string.
import std.range, std.string, std.traits, std.utf;

/++
    Strips leading characters.
  +/
S stripLeft(S)(S s, S charsToStrip) pure
    if(isSomeString!S)
{
    bool foundIt;
    size_t notInSet;
    foreach(i, dchar c; s)
    {
        // Because of the call to indexOf, this function can't be @safe anymore.
        if(indexOf(charsToStrip, c) == -1)
        {
            foundIt = true;
            notInSet = i;
            break;
        }
    }

    if(foundIt)
        return s[notInSet .. $];

    return s[0 .. 0]; //Empty string with correct type.
}

unittest {
    debug(string) printf("string.stripLeft2.unittest\n");

    string hi = "Hello, world!";
    assert(hi.stripLeft("") == hi);
    assert(hi.stripLeft("H") == "ello, world!");
    assert(hi.stripLeft("Hel") == "o, world!");
    assert(hi.stripLeft("def") == hi);
    assert(hi.stripLeft(hi) == "");
}

/++
    Strips trailing characters.
  +/
S stripRight(S)(S s, S charsToStrip)
    if(isSomeString!S)
{
    alias typeof(s[0]) C;
    size_t codeLen;
    foreach(dchar c; retro(s))
    {
        // Because of the call to indexOf, this function can't be @safe anymore.
        if(indexOf(charsToStrip, c) >= 0)
            codeLen += codeLength!C(c);
        else
            break;
    }

    return s[0 .. $ - codeLen];
}

unittest {
    debug(string) printf("string.stripRight2.unittest\n");

    string hi = "Hello, worldd!";
    assert(hi.stripRight("") == hi);
    assert(hi.stripRight("!") == "Hello, worldd");
    assert(hi.stripRight("!.d") == "Hello, worl");
    assert(hi.stripRight("hex") == hi);
    assert(hi.stripRight(hi) == "");
}

/++
    Strips both leading and trailing characters.
  +/
S strip(S)(S s, S charsToStrip)
    if(isSomeString!S)
{
    return stripRight(stripLeft(s, charsToStrip), charsToStrip);
}

unittest {
    debug(string) printf("string.strip2.unittest\n");

    string hi = " ohfoo";
    assert(hi.strip("") == hi);
    assert(hi.strip(" ") == "ohfoo");
    assert(hi.strip(" o") == "hf");
    assert(hi.strip("ext") == hi);
    assert(hi.strip(" ohf") == "");
}
Comment 1 Justin Whear 2014-06-06 21:46:19 UTC
This use case is now covered by the predicate-receiving versions of strip, stripLeft, and stripRight in std.algorithm.