Nhà phát triển của ParseKit tại đây. Tôi sẽ trả lời cả hai câu hỏi của bạn:
1) Bạn đang sử dụng đúng cách, nhưng đây là một trường hợp phức tạp. Có một số gotchas nhỏ, và ngữ pháp của bạn cần phải được thay đổi một chút.
tôi đã phát triển một ngữ pháp mà là làm việc cho tôi:
// Tokenizer Directives
@symbolState = '"' "'"; // effectively tells the tokenizer to turn off QuoteState.
// Otherwise, variables enclosed in quotes would not be found (they'd be embedded in quoted strings).
// now single- & double-quotes will be recognized as individual symbols, not start- & end-markers for quoted strings
@symbols = '${'; // declare '${' as a multi-char symbol
@reportsWhitespaceTokens = YES; // tell the tokenizer to preserve/report whitespace
// Grammar
@start = content*;
content = passthru | variable;
passthru = /[^$].*/;
variable = start name end;
start = '${';
end = '}';
name = Word;
Sau đó thực hiện hai callbacks này trong Assembler của bạn:
- (void)parser:(PKParser *)p didMatchName:(PKAssembly *)a {
NSLog(@"%s %@", __PRETTY_FUNCTION__, a);
PKToken *tok = [a pop];
NSString *name = tok.stringValue;
// do something with name
}
- (void)parser:(PKParser *)p didMatchPassthru:(PKAssembly *)a {
NSLog(@"%s %@", __PRETTY_FUNCTION__, a);
PKToken *tok = [a pop];
NSMutableString *s = a.target;
if (!s) {
s = [NSMutableString string];
}
[s appendString:tok.stringValue];
a.target = s;
}
Và sau đó khách hàng mã/lái xe của bạn sẽ trông giống như này:
NSString *g = // fetch grammar
PKParser *p = [[PKParserFactory factory] parserFromGrammar:g assembler:self];
NSString *s = @"<img src=\"${image}\" />";
[p parse:s];
NSString *result = [p parse:s];
NSLog(@"result %@", result);
Điều này sẽ được in:
result: <img src="" />
2) Vâng, tôi nghĩ rằng nó chắc chắn sẽ tốt hơn nhiều để sử dụng Tokenizer trực tiếp đối với trường hợp tương đối đơn giản này. Hiệu suất sẽ được ồ ạt tốt hơn. Dưới đây là cách bạn có thể tiếp cận công việc với Trình mã thông báo:
PKTokenizer *t = [PKTokenizer tokenizerWithString:s];
[t setTokenizerState:t.symbolState from:'"' to:'"'];
[t setTokenizerState:t.symbolState from:'\'' to:'\''];
[t.symbolState add:@"${"];
t.whitespaceState.reportsWhitespaceTokens = YES;
NSMutableString *result = [NSMutableString string];
PKToken *eof = [PKToken EOFToken];
PKToken *tok = nil;
while (eof != (tok = [t nextToken])) {
if ([@"${" isEqualToString:tok.stringValue]) {
tok = [t nextToken];
NSString *varName = tok.stringValue;
// do something with variable
} else if ([@"}" isEqualToString:tok.stringValue]) {
// do nothing
} else {
[result appendString:tok.stringValue];
}
}
Nguồn
2012-02-16 01:39:34
Cảm ơn Todd! Tôi sẽ lấy cách tiếp cận tokenizer, vì nó có vẻ nhanh hơn và thực hiện phức tạp hơn nhiều. Tôi mong muốn sử dụng một ngữ pháp tại một số điểm, mặc dù. – pgb