比较\ s和\ t

时间:2014-10-05 02:34:41

标签: regex perl

在我的程序中,我存储了@indentation_stack

中显示的缩进级别

例如:

$line =~ /^(\s*)(if|elif|else|while)/
push(@indentation_stack, $1);

然后我将后续行中看到的缩进级别与@indentation_stack的最后一个元素中的缩进级别进行比较。

if ($line =~ /^(\s*)[^\s+]/) {  
    while (@indentation_stack && $1 le $indentation_stack[-1]){         
            print $indentation_stack[-1],"}\n";         
            pop @indentation_stack;         
    }
}

这个想法是,如果后续行上的缩进等同于@indentation_stack的最后一个元素,我会打印}和换行符。

只要缩进由spaces组成,这就可以正常工作。但是,如果我使用\t创建相同级别的缩进,则我的代码无法按预期工作。

EDIT:如果所有间距都一致,则使用全部\t或全部spaces,则没有问题。所以我想我想要解决的是,我怎样才能简单地比较空间。这是\t可能相当于spaces的数量。

有人知道为什么会这样吗?

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

标签与空格的问题是一个没有答案的旧问题,选择一个并保持一致,因为混合两者是不好的。不同的编辑器可以将选项卡显示为不同数量的空格,甚至可以在单个文件中相对于其上下文动态显示。

因此,很多编辑器,emacs是我所知道的,提供了自动将标签转换为空格的方法,并且只有当你点击标签时才插入空格。

此外,您的程序可以选中一定数量的空格,但这可能需要将标签转换为所有行中的空格,而不仅仅是您生成的空格。除非你想做一种混合表示或转换成最接近的标签间距 - 但这很复杂,但没有什么理由。

答案 1 :(得分:1)

您是否在询问如何计算标签的可见长度?选项卡将光标移动到下一个制表位。

use constant TAB_STOP => 4;

sub indent_size {
    my ($s) = @_;
    my $i = 0;
    while ($s =~ /\G([ \t])/g) {
       $i += $1 eq "\t" ? ( TAB_STOP - ($i % TAB_STOP) ) : 1;
    }

    return $i;
}

if (my ($indent) = $line =~ /^([ \t]+)[^ \t\n]/) {  
    my $indent_size = indent_size($indent);
    while (@indent_stack && $indent_size <= indent_size($indent_stack[-1])) {
        print pop(@indent_stack), "}\n";         
    }
}

将缩进及其长度存储在堆栈中会更有效。