digitalmars.D.learn - parse string as char
- Timothee Cour via Digitalmars-d-learn (9/9) Feb 08 2015 Is there a simple way to parse a string as a char?
- Rikki Cattermole (4/14) Feb 08 2015 Ugh, if you are just wanting to get a singular char in a string just you...
- FG (92/100) Feb 09 2015 parseEscape does something similar to what you need:
- FG (11/11) Feb 09 2015 Of course consuming it dchar by dchar also works:
- Kagamin (1/1) Feb 09 2015 https://github.com/Hackerpilot/libdparse/blob/master/src/std/d/lexer.d#L...
Is there a simple way to parse a string as a char? eg: unittest{ assert(parseChar(`a`)=='a'); assert(parseChar(`\n`)=='\n'); //NOTE: I'm looking at `\n` not "\n" // should also work with other forms of characters, see http://dlang.org/lex.html } Note, std.conv.to doesn't work (`\n`.to!char does not work)
Feb 08 2015
On 9/02/2015 3:40 p.m., Timothee Cour via Digitalmars-d-learn wrote:Is there a simple way to parse a string as a char? eg: unittest{ assert(parseChar(`a`)=='a'); assert(parseChar(`\n`)=='\n'); //NOTE: I'm looking at `\n` not "\n" // should also work with other forms of characters, see http://dlang.org/lex.html } Note, std.conv.to <http://std.conv.to> doesn't work (`\n`.to!char does not work)Ugh, if you are just wanting to get a singular char in a string just you slices. assert("mystr"[0] == 'm');
Feb 08 2015
On 2015-02-09 at 03:40, Timothee Cour via Digitalmars-d-learn wrote:Is there a simple way to parse a string as a char? eg: unittest{ assert(parseChar(`a`)=='a'); assert(parseChar(`\n`)=='\n'); //NOTE: I'm looking at `\n` not "\n" // should also work with other forms of characters, see http://dlang.org/lex.html } Note, std.conv.to <http://std.conv.to> doesn't work (`\n`.to!char does not work)parseEscape does something similar to what you need: https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L3415 Unfortunately it is private and handles only escapes, so here is a modified version: import std.range, std.stdio; dchar parseDchar(Source)(ref Source s) if (isInputRange!Source && isSomeChar!(ElementType!Source)) { import std.utf, std.conv; if (s.front != '\\') { dchar c = decodeFront(s); return c; } s.popFront; if (s.empty) throw new Exception("Unterminated escape sequence"); dchar getHexDigit()(ref Source s_ = s) // workaround { import std.ascii : isAlpha, isHexDigit; if (s_.empty) throw new Exception("Unterminated escape sequence"); s_.popFront(); if (s_.empty) throw new Exception("Unterminated escape sequence"); dchar c = s_.front; if (!isHexDigit(c)) throw new Exception("Hex digit is missing"); return isAlpha(c) ? ((c & ~0x20) - ('A' - 10)) : c - '0'; } dchar result; switch (s.front) { case '"': result = '\"'; break; case '\'': result = '\''; break; case '0': result = '\0'; break; case '?': result = '\?'; break; case '\\': result = '\\'; break; case 'a': result = '\a'; break; case 'b': result = '\b'; break; case 'f': result = '\f'; break; case 'n': result = '\n'; break; case 'r': result = '\r'; break; case 't': result = '\t'; break; case 'v': result = '\v'; break; case 'x': result = getHexDigit() << 4; result |= getHexDigit(); break; case 'u': result = getHexDigit() << 12; result |= getHexDigit() << 8; result |= getHexDigit() << 4; result |= getHexDigit(); break; case 'U': result = getHexDigit() << 28; result |= getHexDigit() << 24; result |= getHexDigit() << 20; result |= getHexDigit() << 16; result |= getHexDigit() << 12; result |= getHexDigit() << 8; result |= getHexDigit() << 4; result |= getHexDigit(); break; default: throw new Exception("Unknown escape character " ~ to!string(s.front)); } if (s.empty) throw new Exception("Unterminated escape sequence"); s.popFront(); return result; } dstring parseString(Source)(Source s) if (isInputRange!Source && isSomeChar!(ElementType!Source)) { import std.array; dchar[] result; auto app = appender(result); while (!s.empty) app.put(parseDchar(s)); return app.data; } unittest { assert(parseString(``) == ""d); assert(parseString(`abc`) == "abc"d); assert(parseString(`abc\\n\\n\\n`) == "abc\\n\\n\\n"d); assert(parseString(`ąćę\\nłńó`) == "ąćę\\nłńó"d); assert(parseString(`abc\\\nx`) == "abc\\\nx"d); assert(parseString(`\tabc\r\nx`) == "\tabc\r\nx"d); assert(parseString(` \x20 `) == " "d); }
Feb 09 2015
Of course consuming it dchar by dchar also works: string s = `\tabŁŃ\r\nx`; assert(parseDchar(s) == '\t'); assert(parseDchar(s) == 'a'); assert(parseDchar(s) == 'b'); assert(parseDchar(s) == 'Ł'); assert(parseDchar(s) == 'Ń'); assert(parseDchar(s) == '\r'); assert(parseDchar(s) == '\n'); assert(parseDchar(s) == 'x'); assert(s.empty);
Feb 09 2015