正则表达式替换除小写字母,数字字符,下划线和短划线之外的所有内容

jam*_*iet 0 python regex

我有这个函数,它打算将一个字符串作为输入,并替换任何不是字母,数字,下划线或破折号的东西:

def clean_label_value(label_value):
    """
    GCP Label values have to follow strict guidelines
        Keys and values can only contain lowercase letters, numeric characters, underscores,
        and dashes. International characters are allowed.
    https://cloud.google.com/compute/docs/labeling-resources#restrictions
    :param label_value: label value that needs to be cleaned up
    :return: cleaned label value
    """
    full_pattern = re.compile('[^a-zA-Z0-9]')
    return re.sub(full_pattern, '_', label_value).lower()
Run Code Online (Sandbox Code Playgroud)

我有这个单元测试,成功了

def test_clean_label_value(self):
    self.assertEqual(clean_label_value('XYZ_@:.;\\/,'), 'xyz________')
Run Code Online (Sandbox Code Playgroud)

然而它取代破折号,我不想要它.展示:

def clean_label_value(label_value):
    full_pattern = re.compile('[^a-zA-Z0-9]|-')
    return re.sub(full_pattern, '_', label_value).lower()
Run Code Online (Sandbox Code Playgroud)

但是这个:

def test_clean_label_value(self):
    self.assertEqual(clean_label_value('XYZ-'), 'xyz-')
Run Code Online (Sandbox Code Playgroud)

然后失败了

xyz-!= xyz_

预期:xyz_
实际:xyz-

换句话说,它-正在被替换为_.我不希望这种情况发生.我已经摆弄了正则表达式,尝试了各种不同的组合,但我无法想象出那些愚蠢的东西.任何人?

Håk*_*Lid 5

-在集合的开头或结尾放置一个(字符类).然后它不会创建字符范围,而是表示文字-字符本身.

re.compile('[^-a-zA-Z0-9]')
Run Code Online (Sandbox Code Playgroud)

也可以-使用a \来表示它是一个文字短划线字符,而不是一个集合中的范围运算符.

re.compile(r'[^\-\w]')
Run Code Online (Sandbox Code Playgroud)

特殊序列\w相当于集合[a-zA-Z0-9_]("w"表示"单词字符").