【问题标题】:Why isn't the case statement case-sensitive when nocasematch is off?当 nocasematch 关闭时,为什么 case 语句不区分大小写?
【发布时间】:2012-05-28 12:44:16
【问题描述】:

鉴于以下情况:

$ echo $BASH_VERSION
4.2.10(1)-release

$ shopt | fgrep case
nocaseglob      off
nocasematch     off

$ case A in [a-z]) echo TRUE;; esac
TRUE

我希望大写字母 A[a-z] 的小写字符类匹配,但它确实如此。为什么这个匹配没有失败?

【问题讨论】:

  • nocaseglob 不相关:If set, bash matches filenames in a case-insensitive fashion when performing pathname expansion (see Pathname Expansion above),尽管行为仍然很奇怪。

标签: bash pattern-matching


【解决方案1】:

您不能以这种方式可靠地使用破折号。如果我不使用破折号,它会按预期工作:

$ bash --version
GNU bash, version 4.2.10(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ shopt -s nocasematch
$ case A in [abc]) echo TRUE;; esac
TRUE
$ shopt -u nocasematch
$ case A in [abc]) echo TRUE;; esac
$ 

但是带有破折号,不管nocasematch的设置如何,它都会打印出TRUE。

Bash 在这里进行模式匹配。查看this section of the reference manual,它说使用连字符可能会将[a-z] 解释为[A-Za-z]!它告诉您如何获得传统解释(将 LC_COLLATE 或 LC_ALL 设置为 C)。基本上,您的默认语言环境是按字典顺序排序的。参考手册解释得很好。

附录

好的,我有一份成绩单给你。

$ shopt -u nocasematch
$ case A in [a-z]) echo TRUE;; esac
TRUE
$ shopt -s nocasematch
$ case A in [a-z]) echo TRUE;; esac
TRUE
$ LC_ALL=C
$ shopt -u nocasematch
$ case A in [a-z]) echo TRUE;; esac
$ shopt -s nocasematch
$ case A in [a-z]) echo TRUE;; esac
TRUE

【讨论】:

    【解决方案2】:

    这与您的区域设置有关。具体来说,整理顺序是不区分大小写的。

    例如,将LC_COLLATE 设置为en_AU.utf8(我的系统上的默认值),您可以看到它包含小写和大写:

    pax> case A in [a-b]) echo TRUE;; esac
    TRUE
    pax> _
    

    但是,如果你去掉范围说明符,它会按预期工作:

    pax> case A in [ab]) echo TRUE;; esac
    pax> _
    

    这是因为第一个表示between a and b inclusive,对于该整理序列,包括A。对于后者,仅表示 ab,而不是受整理顺序影响的范围。

    如果您将整理顺序设置为区分大小写的顺序,它会按预期工作:

    pax> export LC_COLLATE="C"
    pax> case A in [a-b]) echo TRUE;; esac
    pax> 
    

    如果您只想将其作为一次性操作执行而不影响其他任何操作,则可以在子 shell 中执行:

    ( export LC_COLLATE="C" ; case A in [a-b]) echo TRUE;; esac )
    

    【讨论】:

      猜你喜欢
      • 2013-10-11
      • 2010-09-14
      • 2014-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-14
      • 2011-11-17
      相关资源
      最近更新 更多