我试图以Hpricot/Nokogiri类型的方式解析而不是评估Rails ERB文件。我尝试解析的文件包含HTML片段,这些片段与使用ERB(标准rails View 文件)生成的动态内容混合在一起,我正在寻找一个不仅可以解析周围内容的库,而且可以像Hpricot或Nokogiri那样处理, ERB符号
理想情况下,我会得到类似DOM的结构,其中
我知道可以使用正则表达式将某些东西合并在一起,但是我正在寻找更可靠的东西,因为我正在开发一个需要在非常大的 View 代码库(HTML内容和erb内容都可以运行)上运行的工具是重要的。
例如,诸如以下内容:
等等等等等等
将返回一个像这样的树结构:
根
-text_node(等等等等)
-元素(div)
-text_node(我的伟大文本)
-erb_node(
最佳答案
我最终通过使用带有以下语法的Lex的Ruby版本RLex http://raa.ruby-lang.org/project/ruby-lex/解决了这个问题:
%{
#定义NUM 257
#定义OPTOK 258
#定义IDENT 259
#定义OPETOK 260
#定义CLSTOK 261
#定义CLTOK 262
#定义FLOAT 263
#define FIXNUM 264
#定义WORD 265
#定义STRING_DOUBLE_QUOTE 266
#define STRING_SINGLE_QUOTE 267
#定义TAG_START 268
#定义TAG_END 269
#定义TAG_SELF_CONTAINED 270
#define ERB_BLOCK_START 271
#define ERB_BLOCK_END 272
#define ERB_STRING_START 273
#define ERB_STRING_END 274
#define TAG_NO_TEXT_START 275
#定义TAG_NO_TEXT_END 276
#define WHITE_SPACE 277
%}
数字[0-9]
空白的 [ ]
字母[A-Za-z]
名称1 [A-Za-z_]
名称2 [A-Za-z_0-9]
valid_tag_character [A-Za-z0-9“'= @ _():/]
ignore_tags样式|脚本
%%
{blank} +“\n” {返回[WHITE_SPACE,yytext]}
“\n” {空白} + {返回[WHITE_SPACE,yytext]}
{blank} +“\n” {blank} + {return [WHITE_SPACE,yytext]}
“\r” {返回[WHITE_SPACE,yytext]}
“\n” {return [yytext [0],yytext [0..0]]};
“\t” {return [yytext [0],yytext [0..0]]};
^ {空白} + {返回[WHITE_SPACE,yytext]}
{blank} + $ {return [WHITE_SPACE,yytext]};
“” {返回[TAG_NO_TEXT_START,yytext]}
“” {返回[TAG_NO_TEXT_END,yytext]}
“” {返回[TAG_SELF_CONTAINED,yytext]}
“” {返回[TAG_SELF_CONTAINED,yytext]}
“” {返回[TAG_START,yytext]}
“” {返回[TAG_END,yytext]}
“” {返回[ERB_BLOCK_END,yytext]}
“” {返回[ERB_STRING_END,yytext]}
{letter} + {return [WORD,yytext]}
\“。*\” {返回[STRING_DOUBLE_QUOTE,yytext]}
'。*'{return [STRING_SINGLE_QUOTE,yytext]}
。 {return [yytext [0],yytext [0..0]]}
%%
这不是一个完整的语法程序,但出于我的目的,找到并重新发送文本可以正常工作。我将该语法与这小段代码结合在一起:
text_handler = MakeYourOwnCallbackHandler.new
l = Erblex.new
l.yyin = File.open(file_name,“r”)
循环做
a,v = l.yylex
如果a == 0则中断
if(一个 text_handler.character(v.to_s,a)
别的
情况一
当WORD
text_handler.text(v.to_s)
TAG_START时
text_handler.start_tag(v.to_s)
TAG_END时
text_handler.end_tag(v.to_s)
当WHITESPACE
text_handler.white_space(v.to_s)
当ERB_BLOCK_START
text_handler.erb_block_start(v.to_s)
当ERB_BLOCK_END
text_handler.erb_block_end(v.to_s)
当ERB_STRING_START
text_handler.erb_string_start(v.to_s)
当ERB_STRING_END
self.text_handler.erb_string_end(v.to_s)
TAG_NO_TEXT_START时
text_handler.ignorable_tag_start(v.to_s)
TAG_NO_TEXT_END时
text_handler.ignorable_tag_end(v.to_s)
当STRING_DOUBLE_QUOTE
text_handler.string_double_quote(v.to_s)
当STRING_SINGLE_QUOTE
text_handler.string_single_quote(v.to_s)
当TAG_SELF_CONTAINED
text_handler.tag_self_contained(v.to_s)
结尾
结尾
结尾