Add RegexSplit()

console-destruction
Lukas Werling 2016-09-18 11:10:19 +02:00
parent 219f81f004
commit fbb8ad5d87
5 changed files with 101 additions and 1 deletions

View File

@ -56,6 +56,7 @@
<related>
<funclink>RegexSearch</funclink>
<funclink>RegexReplace</funclink>
<funclink>RegexSplit</funclink>
</related>
</func>
<author>Luchs</author><date>2016-09</date>

View File

@ -62,6 +62,7 @@
<funclink>ReplaceString</funclink>
<funclink>RegexSearch</funclink>
<funclink>RegexMatch</funclink>
<funclink>RegexSplit</funclink>
</related>
</func>
<author>Luchs</author><date>2016-09</date>

View File

@ -49,13 +49,14 @@
</desc>
<examples>
<example>
<code><funclink>Log</funclink>("%d", RegexSearch("hello world", "l"));</code>
<code><funclink>Log</funclink>("%v", RegexSearch("hello world", "l"));</code>
<text>Searches for the character l, returning [2, 3, 9].</text>
</example>
</examples>
<related>
<funclink>RegexReplace</funclink>
<funclink>RegexMatch</funclink>
<funclink>RegexSplit</funclink>
</related>
</func>
<author>Luchs</author><date>2016-09</date>

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>RegexSplit</title>
<category>Script</category>
<subcat>Strings</subcat>
<version>8.0 OC</version>
<syntax>
<rtype>array</rtype>
<params>
<param>
<type>string</type>
<name>text</name>
<desc>String to split in parts.</desc>
</param>
<param>
<type>string</type>
<name>regex</name>
<desc>Regular expression matching the separator in ECMAScript syntax.</desc>
</param>
<param>
<type>int</type>
<name>flags</name>
<desc>
Bitmask of the following values:
<table>
<rowh>
<col>Constant</col>
<col>Description</col>
</rowh>
<row>
<literal_col>Regex_CaseInsensitive</literal_col>
<col>Regular expression is case insensitive.</col>
</row>
<row>
<literal_col>Regex_FirstOnly</literal_col>
<col>Split the string only once.</col>
</row>
</table>
</desc>
</param>
</params>
</syntax>
<desc>
Splits a string into an array of strings.
</desc>
<examples>
<example>
<code><funclink>Log</funclink>("%v", RegexSplit("Harry!, Sven2 &amp; Maikel", "\\s*[,&amp;]\\s*"));</code>
<text>Splits a list of names, returning ["Harry!", "Sven2", "Maikel"].</text>
</example>
</examples>
<related>
<funclink>RegexSearch</funclink>
<funclink>RegexReplace</funclink>
<funclink>RegexMatch</funclink>
</related>
</func>
<author>Luchs</author><date>2016-09</date>
</funcs>

View File

@ -566,6 +566,39 @@ static Nillable<C4ValueArray *> FnRegexMatch(C4PropList * _this, C4String *sourc
}
}
static Nillable<C4ValueArray *> FnRegexSplit(C4PropList * _this, C4String *source, C4String *regex, long flags)
{
if (!source || !regex) return C4Void();
try
{
std::regex re(regex->GetCStr(), C4IntToSyntaxOption(flags));
C4ValueArray *out = new C4ValueArray();
const auto &data = source->GetData();
size_t pos = 0;
std::cmatch m;
long i = 0;
while (pos <= data.getLength() && std::regex_search(data.getData() + pos, data.getData() + data.getLength(), m, re))
{
// As we're advancing by one character for zero-length matches, always
// include at least one character here.
std::string substr(data.getData() + pos, std::max(m.position(), 1l));
(*out)[i++] = C4VString(String(substr.c_str()));
if (flags & Regex_FirstOnly) break;
pos += m.position() + std::max(m.length(), 1l);
}
if (pos <= data.getLength())
{
std::string substr(data.getData() + pos, data.getLength() - pos);
(*out)[i++] = C4VString(String(substr.c_str()));
}
return out;
}
catch (const std::regex_error& e)
{
throw C4AulExecError(FormatString("RegexSplit: %s", e.what()).getData());
}
}
static C4Value FnLog(C4PropList * _this, C4Value * Pars)
{
@ -1139,6 +1172,7 @@ void InitCoreFunctionMap(C4AulScriptEngine *pEngine)
F(RegexReplace);
F(RegexSearch);
F(RegexMatch);
F(RegexSplit);
F(Distance);
F(Angle);
F(GetChar);