问题:
看看我的“扫描”功能。这决定了字符串中匹配的位置。(顺便说一下,这是鳗鱼代码,它是一种非常类似C的语言)。我如何开始添加一个正则表达式的匹配?我的意图是一个正则表达式启发的功能,因为我不希望或需要复制regex行为准确。具体来说,我想窃取regex的\d功能,基本上是一个字符类,意思是“匹配从'0‘到'9’的任何字符。
示例:"abc \d\d“与”abc 123“匹配;
任何解释,有帮助的提示,开始添加这种功能将不胜感激!
详情:
这是我的“双向字符串扫描器”函数,它输出一个子字符串。这是双向的,因为您必须指定两个匹配( m1 m2 ),两个“在停止之前要匹配多少次?”(称为ntimes1 ntimes2)起始位置p1,当然还有要扫描的字符串(干草堆)。
它可以向前移动'ff‘,向后移动'bb’,向后移动'bf‘,然后向后移动'fb’。
例如,,假设您想要在中第二次出现"abc“之前的数字
abc,1,def,4,ghi,5,abc,2,def,6,ghi,3
从0开始,向前移动两次,匹配"abc“两次,向后移动:”匹配",“两次”
子字符串= ",5,abc“(当前子字符串包括所有匹配字符串)
和它工作得很好!
代码:
function scan(match,str,p,D,ntimes,mlen,hlen) local(lastp found break restart) (
D == -1 ? (m=restart=mlen-1; end=-1) : (m=restart=0; end=mlen);
found=break=0;
while(p > -1 && p < hlen && !break) (
//ShowConsoleMsg(sprintf(#, "%i:%i -> ' %c ' = ' %c '\n", m,p,str_getchar(match, m),str_getchar(str, p)));
str_getchar(match, m) == str_getchar(str, p) ? m+=D : m=restart;
m == end ? (found+=1; m=restart; lastp=p);
found == ntimes ? break=1 : p+=D;
);
ntimes == -1 ? lastp : p;
);
function findpos(m1,m2,DIR,p1,ntimes1,ntimes2) local(adj start p1 p2 len1 len2 dir1 dir2 hlen) (
hlen = strlen(this);
len1 = strlen(m1);
len2 = strlen(m2);
ntimes1 < 1 ? ntimes1 = -1;
ntimes2 < 1 ? ntimes2 = -1;
DIR == 'ff' ? (dir1 = dir2 = +1; adj=1):
DIR == 'fb' ? (dir1 = +1; dir2 = -1; adj=1):
DIR == 'bf' ? (dir1 = -1; dir2 = +1; adj=1):
(dir1 = dir2 = -1; adj=len1);
p1 = scan(m1,this,p1,dir1,ntimes1,len1,hlen);
DIR == 'ff' ? (p2=p1+len1+dir1; p1+=dir1-len1):
DIR == 'bf' ? (p2=p1+len1):
(p2=p1-len1);
//ShowConsoleMsg(sprintf(#, "%i---------%i\n", p1,p2));
p2 = scan(m2,this,p2,dir2,ntimes2,len2,hlen);
dir2 == 1 ? (p2+=len; this.pos1 = p1; this.pos2 = p2):
DIR == 'fb' ? (p2+=len; this.pos1 = p2; this.pos2 = p1):
(this.pos1 = p2; this.pos2 = p1);
//ShowConsoleMsg(sprintf(#, "%i---------%i\n", p1,p2));
this.substrlen = this.pos2-this.pos1+adj;
strcpy_substr(#, this, this.pos1, this.substrlen);
);使用示例:
ShowConsoleMsg("");
string = "C-2=0,C#-2=1,D-2=2,D#-2=3,";
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos(",",",",'ff',8,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos(",",",",'fb',15,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos(",",",",'bf',15,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos(",",",",'bb',21,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos("1,",",D",'ff',8,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos(",D","1,",'fb',15,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos("1,",",D",'bf',15,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos(",D","1,",'bb',21,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos("1,",",",'ff',8,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos(",","1,",'fb',15,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos("1,",",",'bf',15,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos(",","1,",'bb',21,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos(",",",D",'ff',8,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos(",D",",",'bb',21,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos(",",",D",'bf',16,1,1)) );
ShowConsoleMsg( sprintf(#, "%s\n",string.findpos(",D",",",'fb',15,1,1)) );产出:
,D-2=2,
,D-2=2,
,D-2=2,
,D-2=2,
1,D-2=2,D
1,D-2=2,D
1,D-2=2,D
1,D-2=2,D
1,D-2=2,
1,D-2=2,
1,D-2=2,
1,D-2=2,
,D-2=2,D
,D-2=2,D
,D-2=2,D
,D-2=2,D发布于 2014-11-22 01:12:24
实际上我还没有运行您的代码,但是快速查看一下,我想您想要更改这一行:
str_getchar(match, m) == str_getchar(str, p) ? m+=D : m=restart; 现在,它寻找一个完全匹配的字符。您可以更改它,以便如果搜索字符串是魔术字符类字符,它将检查范围,而不是检查确切的内容。
所以就像
char c = str_getchar(match, m);
if(c == magic_thing) {
char n = str_getchar(str, p);
(n >= '0' && n <= '9') ? m+=D : m=restart;
else
c == str_getchar(str, p) ? m +=D : m=restart;
}在那里面。要执行magic_thing,您可以修改str_getchar (或为它编写一个包装器),以检查\。如果它在那里,也读下一个字符。如果它是'd',返回魔法意符。否则,返回字符本身。您可能会采取一些不同的做法,但通常我希望将\d识别放在读字符串函数中,而不是尝试将其作为扫描函数本身的一部分。
https://stackoverflow.com/questions/27072653
复制相似问题