比较完整的编辑器自动完成文件(使用正则自动提取)

tuja 2007-05-03
比较完整的编辑器自动完成文件(使用正则自动提取)
下面代码能够自动提取并生成自动完成文件。

1 问题,正则如何让.匹配换行符?
2 请各位提出建议,代码中哪些地方可以进一步改进

import std.stdio : writefln;		
import std.file;		//for read append
import std.string	: replace;	
import std.regexp;

char[] helpPath = r"D:\dmd\html\d\phobos\";	//标准库帮助文件所在目录
char[] api = r"D:\SciTe\api\d.api";			//自动完成文件,用于Scite或其他编辑器
	
void main(char[][] args)
 {
    auto d_help_files = std.file.listdir(helpPath, "*.html");
	char[] source;		//html源文件
	char[] patternH1 = r"<h1>\s*(.+?[.].+?)\s*</h1>";		//匹配形如 std.file
	//匹配方法名字,包括返回值类型
	//<dt><big>void[] <u>read</u>(char[] <i>name</i>);
	char[] patternFunc =r"<dt><big>[^\r\n]+?\s+<u>\w+</u>\([^\r\n()]+?\);";	
	char[][] h1;		//保存模块文件名,如std.file
	char[][] func;		//保存方法名
	 
    foreach (d; d_help_files)
	{
		source = cast(char[])read(d);
		if ( RegExp(patternH1).test(source) ) 
		{
			h1 ~= RegExp(patternH1,"i").match(source)[1];
		}
		//~ else {writefln("failed h1");}
		
		if ( RegExp(patternFunc).test(source) ) 
		{
			func ~= RegExp(patternFunc,"ig").match(source);
		}		
		//~ else {writefln("failed func");}
	}
	
	foreach (int i,char[] d;func)
	{
		//去掉html标签
		d = sub(d,"<[^<>]+>","","g");
		//返回值移到方法名字后面
		auto m = RegExp(r"(.+?)(\w+\(.+)").match(d);
		d = m[2] ~ " " ~ m[1];
		func[i] = d ;
		//~ writefln("%d=%s",i,func[i]);
	}

	//把数组内容写到文件,可以作为SciTE的自动提示api文件
	foreach (d;h1)
	{
		append(api,d ~ "\r\n");	
	}
	foreach (d;func)
	{
		append(api,d ~ "\r\n");
	}

	//D语言正则表达式.不能匹配新行符,也没有象其他语言一样s开关可以切换.是否匹配换行符
	//笨办法先把所有\r\n删除
	char[] lex = cast(char[]) read(r"D:\dmd\html\d\lex.html");	//提取D语言关键词
	lex = sub(lex,r"[\r\n]","","g");
	char[] patternKeys = r"<b>abstract</b>.+?<b>with</b>";
	if ( RegExp(patternKeys,"ig").test(lex) ) 
	{
		lex = RegExp(patternKeys,"img").match(lex)[0];
		lex = std.string.replace(lex,"<b>","");
		lex = sub(lex,r"</b>\s*","\r\n","g");
		append(api,lex);		
	}	
	else {writefln("failed lex");}
 }
qiezi 2007-05-03
文档里有:

g global; repeat over the whole input string
i case insensitive
m treat as multiple lines separated by newlines
tuja 2007-05-03
不行啊,无论加上什么Attribute(igm,或ig),如果源文件有换行符,总是失败:
    char[] lex = cast(char[]) read(r"D:\dmd\html\d\lex.html");  //提取D语言关键词   
    //lex = sub(lex,r"[\r\n]","","g");   
    char[] patternKeys = r"<b>abstract</b>.+?<b>with</b>";
    if ( RegExp(patternKeys,"ig").test(lex) )如果源文件有换行符,这里总是失几败   
    
    {   
        lex = RegExp(patternKeys,"img").match(lex)[0];   
        lex = std.string.replace(lex,"<b>","");   
        lex = sub(lex,r"</b>\s*","\r\n","g");   
        append(api,lex);           
    }      
    else {writefln("failed lex");} 
tuja 2007-05-03
要这样才行:
char[] patternKeys = r"<b>abstract</b>(.|\s)+?<b>with</b>";


这样也不行:
char[] patternKeys = r"<b>abstract</b>[.\s]+?<b>with</b>";


谁能举例说明.可以跨行吗
qiezi 2007-05-03
大概是phobos的regexp库的一个BUG吧,没有m时"."匹配的是除回车符以外的所有字符,有m时"."符号匹配所有字符,看来它有些问题。我用ruby的正则表达式就没有这个问题。。

它这个m有没有效果都一样。
tuja 2007-05-04
这个bug 2005年就存在了:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.bugs&article_id=4747

So it seams that "." dos not match any character, as it misses newline.

Regards
Fredrik Olsson



一年多了还没有修复,真是。。。
D的正则确实是有点弱。