我正在编写一个文本解析器,它需要能够从行中删除注释。我使用的是一种相当简单的语言,其中所有注释均由#字符启动,并且删除此后的所有内容将很简单,但是我必须处理#位于字符串内部的可能性。
因此,我的问题是给出一个字符串,例如
Value="String#1";"String#2"; # This is an array of "-delimited strings, "Like this"
如何最好地提取子字符串
Value="String#1";"String#2";
(注意尾随空格)
请注意,注释可能包含引号,并且整行可以在“和”之间进行选择,尽管它在整行中是一致的。如果这很重要,则这是事先已知的。字符串中的引号将被转义一种 \
std::string stripComment(std::string str) {
bool escaped = false;
bool inSingleQuote = false;
bool inDoubleQuote = false;
for(std::string::const_iterator it = str.begin(); it != str.end(); it++) {
if(escaped) {
escaped = false;
} else if(*it == '\\' && (inSingleQuote || inDoubleQuote)) {
escaped = true;
} else if(inSingleQuote) {
if(*it == '\'') {
inSingleQuote = false;
}
} else if(inDoubleQuote) {
if(*it == '"') {
inDoubleQuote = false;
}
} else if(*it == '\'') {
inSingleQuote = true;
} else if(*it == '"') {
inDoubleQuote = true;
} else if(*it == '#') {
return std::string(str.begin(), it);
}
}
return str;
}
编辑:或更多教科书FSM,
std::string stripComment(std::string str) {
int states[5][4] = {
// \ ' "
{0, 0, 1, 2,}
{1, 3, 0, 1,}, //single quoted string
{2, 4, 2, 0,}, //double quoted string
{1, 1, 1, 1,}, //escape in single quoted string
{2, 2, 2, 2,}, //escape in double quoted string
};
int state = 0;
for(std::string::const_iterator it = str.begin(); it != str.end(); it++) {
switch(*it) {
case '\\':
state = states[state][1];
break;
case '\'':
state = states[state][2];
break;
case '"':
state = states[state][3];
break;
case '#':
if(!state) {
return std::string(str.begin(), it);
}
default:
state = states[state][0];
}
}
return str;
}
该states
数组定义了FSM状态之间的转换。
第一指标是当前状态,0
,1
,2
,3
,或4
。
所述第二索引对应于字符,\
,'
,"
,或其它字符。
数组根据当前状态和字符告诉下一个状态。
仅供参考,这些假设反斜杠转义了字符串中的任何字符。您至少需要它们转义反斜杠,因此您可以使用以反斜杠结尾的字符串。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句