【问题标题】:Tcl: Package wrapping regsub and string map *** Looking for side effects ***Tcl: 封装 regsub 和字符串映射 *** 寻找副作用 ***
【发布时间】:2015-04-09 21:52:31
【问题描述】:

我用四个新命令制作了以下软件包,以简化regsubmap 的使用。我使用这些命令已经有一段时间了,到目前为止运行良好。我想知道代码是否有任何弱点,将来可能会产生不良结果或错误。

regdel varName args(从 varName 正则表达式中删除匹配 args

mapdel varName args(从 varName 字符串中移除匹配 args

regrep varName exp repl(将 varName 中的 exp 替换为 repl)

maprep varName string repl(将 varName 中的 string 替换为 repl)

使用 regdel 删除数字

regdel inputFile {[[:digit:]]} 

使用 mapdel 删除数字

mapdel inputFile 0 1 2 3 4 5 6 7 8 9

使用 regrep 替换空白字符

regrep inputFile {[[:space:]]+} \n

使用 mapprep 替换空白字符

maprep inputFile " " \n

包装代码:

package provide myregex 1.0

proc regdel {ref args} {
    upvar 1 $ref var
    foreach match $args {
        regsub -all $match $var "" var
    } 
}

proc mapdel {ref args} {
    upvar 1 $ref var
    foreach match $args {
        set var [string map [list "$match" ""] $var]
    } 
}

proc regrep {ref match repl} {
    upvar 1 $ref var 
    regsub -all $match $var $repl var
}
proc maprep {ref match repl} {
    upvar 1 $ref var
    set var [string map [list "$match" "$repl"] $var]
}

【问题讨论】:

    标签: regex tcl


    【解决方案1】:

    为了避免冲突,我会将你的 procs 放在一个命名空间中:

    http://www.tcl.tk/man/tcl8.6/TclCmd/namespace.htm

    package provide myregex 1.0
    namespace eval myregex {
        namespace export regdel mapdel regrep maprep
        # your code here
    }
    

    那么,当你使用它时:

    package require myregex
    
    myregex::mapdel file foo bar baz
    
    # or, you decide the risk of collisions in the global namespace
    namespace import myregex::*
    mapdel file foo bar baz
    

    我不太喜欢你的 proc 名称:regrep 看起来像 re-grep。考虑子命名空间

    namespace eval myregex {
        namespace export regex map
    }
    
    namespace eval myregex::regex {
        proc del args ...
        proc rep args ...
    }
    
    namespace eval myregex::map {
        proc del args ...
        proc rep args ...
    }
    

    然后

    namespace import myregex::*
    map::del file foo bar baz
    regex::rep file hello world
    

    使用 Donal 的合奏建议:

    namespace eval myregex {
        namespace export regex map
        namespace eval regex {
            proc del {varname args} {
                if {[llength $args] == 0} return
                upvar 1 $varname var
                regsub -all [join $args "|"] $var "" var
            }
            proc rep {varname args} {
                if {[llength $args] == 0} return
                upvar 1 $varname var
                foreach {pattern replacement} $args {
                    regsub -all $pattern $var $replacement var
                }
            }
            namespace ensemble create
            namespace export *
        }
        namespace eval map {
            namespace ensemble create
            proc del {varname args} {
                if {[llength $args] == 0} return
                upvar 1 $varname var
                foreach substr $args {
                    lappend map $substr ""
                }
                set var [string map $map $var]
            }
            proc rep {varname args} {
                if {[llength $args] == 0} return
                upvar 1 $varname var
                set var [string map $args $var]
            }
            namespace ensemble create
            namespace export *
        }
    }
    

    然后

    namespace import myregex::*
    
    set str "hello world"; regex del str l d;     puts $str
    set str "hello world"; regex rep str l L o O; puts $str
    set str "hello world"; map del str l d;       puts $str
    set str "hello world"; map rep str l L o O;   puts $str
    

    输出

    heo wor
    heLLO wOrLd
    heo wor
    heLLO wOrLd
    

    【讨论】:

    • 我建议制作合奏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多