advancePast

Given some string, finds the supplied needle token in it, returns the string up to that point, and advances the passed string by ref to after the token.

The closest equivalent in Phobos is std.algorithm.searching.findSplit, which largely serves the same function but doesn't advance the input string.

Additionally takes an optional inherit bool argument, to toggle whether the return value inherits the passed line (and clearing it) upon no needle match.

@safe @safe
advancePast
(
Haystack
Needle
)
(
auto ref return scope Haystack haystack
,
const scope Needle needle
,
const bool inherit = false
,
const string callingFile = __FILE__
,
const size_t callingLine = __LINE__
)

Parameters

haystack Haystack

Array to walk and advance.

needle Needle

Token that delimits what should be returned and to where to advance. May be another array or some individual character.

inherit bool

Optional flag of whether or not the whole string should be returned and the haystack variable cleared on no needle match.

callingFile string

Optional file name to attach to an exception.

callingLine size_t

Optional line number to attach to an exception.

Return Value

Type: auto

The string haystack from the start up to the needle token. The original variable is advanced to after the token.

Throws

AdvanceException if the needle could not be found in the string.

Examples

string foobar = "foo bar!";
string foo = foobar.advancePast(" ");
string bar = foobar.advancePast("!");

assert((foo == "foo"), foo);
assert((bar == "bar"), bar);
assert(!foobar.length);

enum line = "abc def ghi";
string def = line[4..$].advancePast(" ");  // now with auto ref

string foobar2 = "foo bar!";
string foo2 = foobar2.advancePast(" ");
string bar2 = foobar2.advancePast("?", inherit: true);

assert((foo2 == "foo"), foo2);
assert((bar2 == "bar!"), bar2);
assert(!foobar2.length);

string slice2 = "snarfl";
string verb2 = slice2.advancePast(" ", inherit: true);

assert((verb2 == "snarfl"), verb2);
assert(!slice2.length, slice2);
1 import std.conv : to;
2 import std.string : indexOf;
3 
4 {
5     string line = "Lorem ipsum :sit amet";
6     immutable lorem = line.advancePast(" :");
7     assert(lorem == "Lorem ipsum", lorem);
8     assert(line == "sit amet", line);
9 }
10 {
11     string line = "Lorem ipsum :sit amet";
12     //immutable lorem = line.advancePast(" :");
13     immutable lorem = line.advancePast(" :");
14     assert(lorem == "Lorem ipsum", lorem);
15     assert(line == "sit amet", line);
16 }
17 {
18     string line = "Lorem ipsum :sit amet";
19     immutable lorem = line.advancePast(':');
20     assert(lorem == "Lorem ipsum ", lorem);
21     assert(line == "sit amet", line);
22 }
23 {
24     string line = "Lorem ipsum :sit amet";
25     immutable lorem = line.advancePast(':');
26     assert(lorem == "Lorem ipsum ", lorem);
27     assert(line == "sit amet", line);
28 }
29 {
30     string line = "Lorem ipsum :sit amet";
31     immutable lorem = line.advancePast(' ');
32     assert(lorem == "Lorem", lorem);
33     assert(line == "ipsum :sit amet", line);
34 }
35 {
36     string line = "Lorem ipsum :sit amet";
37     immutable lorem = line.advancePast(' ');
38     assert(lorem == "Lorem", lorem);
39     assert(line == "ipsum :sit amet", line);
40 }
41 /*{
42     string line = "Lorem ipsum :sit amet";
43     immutable lorem = line.advancePast("");
44     assert(!lorem.length, lorem);
45     assert(line == "Lorem ipsum :sit amet", line);
46 }*/
47 /*{
48     string line = "Lorem ipsum :sit amet";
49     immutable lorem = line.advancePast("");
50     assert(!lorem.length, lorem);
51     assert(line == "Lorem ipsum :sit amet", line);
52 }*/
53 {
54     string line = "Lorem ipsum :sit amet";
55     immutable lorem = line.advancePast("Lorem ipsum");
56     assert(!lorem.length, lorem);
57     assert(line == " :sit amet", line);
58 }
59 {
60     string line = "Lorem ipsum :sit amet";
61     immutable lorem = line.advancePast("Lorem ipsum");
62     assert(!lorem.length, lorem);
63     assert(line == " :sit amet", line);
64 }
65 {
66     string line = "Lorem ipsum :sit amet";
67     immutable dchar dspace = ' ';
68     immutable lorem = line.advancePast(dspace);
69     assert(lorem == "Lorem", lorem);
70     assert(line == "ipsum :sit amet", line);
71 }
72 {
73     dstring dline = "Lorem ipsum :sit amet"d;
74     immutable dspace = " "d;
75     immutable lorem = dline.advancePast(dspace);
76     assert((lorem == "Lorem"d), lorem.to!string);
77     assert((dline == "ipsum :sit amet"d), dline.to!string);
78 }
79 {
80     dstring dline = "Lorem ipsum :sit amet"d;
81     immutable wchar wspace = ' ';
82     immutable lorem = dline.advancePast(wspace);
83     assert((lorem == "Lorem"d), lorem.to!string);
84     assert((dline == "ipsum :sit amet"d), dline.to!string);
85 }
86 {
87     wstring wline = "Lorem ipsum :sit amet"w;
88     immutable wchar wspace = ' ';
89     immutable lorem = wline.advancePast(wspace);
90     assert((lorem == "Lorem"w), lorem.to!string);
91     assert((wline == "ipsum :sit amet"w), wline.to!string);
92 }
93 {
94     wstring wline = "Lorem ipsum :sit amet"w;
95     immutable wspace = " "w;
96     immutable lorem = wline.advancePast(wspace);
97     assert((lorem == "Lorem"w), lorem.to!string);
98     assert((wline == "ipsum :sit amet"w), wline.to!string);
99 }
100 {
101     string user = "foo!bar@asdf.adsf.com";
102     user = user.advancePast('!');
103     assert((user == "foo"), user);
104 }
105 {
106     immutable def = "abc def ghi"[4..$].advancePast(" ");
107     assert((def == "def"), def);
108 }
109 {
110     import std.exception : assertThrown;
111     assertThrown!AdvanceException("abc def ghi"[4..$].advancePast(""));
112 }
113 {
114     string line = "Lorem ipsum";
115     immutable head = line.advancePast(" ");
116     assert((head == "Lorem"), head);
117     assert((line == "ipsum"), line);
118 }
119 {
120     string line = "Lorem";
121     immutable head = line.advancePast(" ", inherit: true);
122     assert((head == "Lorem"), head);
123     assert(!line.length, line);
124 }
125 {
126     string slice = "verb";
127     string verb;
128 
129     if (slice.indexOf(' ') != -1)
130     {
131         verb = slice.advancePast(' ');
132     }
133     else
134     {
135         verb = slice;
136         slice = string.init;
137     }
138 
139     assert((verb == "verb"), verb);
140     assert(!slice.length, slice);
141 }
142 {
143     string slice = "verb";
144     immutable verb = slice.advancePast(' ', inherit: true);
145     assert((verb == "verb"), verb);
146     assert(!slice.length, slice);
147 }
148 {
149     string url = "https://google.com/index.html#fragment-identifier";
150     url = url.advancePast('#', inherit: true);
151     assert((url == "https://google.com/index.html"), url);
152 }
153 {
154     string url = "https://google.com/index.html";
155     url = url.advancePast('#', inherit: true);
156     assert((url == "https://google.com/index.html"), url);
157 }
158 {
159     string line = "Lorem ipsum sit amet";
160     string[] words;
161 
162     while (line.length > 0)
163     {
164         immutable word = line.advancePast(" ", inherit: true);
165         words ~= word;
166     }
167 
168     assert(words == [ "Lorem", "ipsum", "sit", "amet" ]);
169 }
170 {
171     import std.exception : assertThrown;
172     string url = "https://google.com/index.html#fragment-identifier";
173     assertThrown!AdvanceException(url.advancePast("", inherit: true));
174 }