正则表达式解析docker标签?

时间:2016-09-24 01:28:29

标签: regex

'registry/rabbit',
'registry/rabbit:3',
'rabbit',
'rabbit:3'

尝试在上述四种情况下提出与rabbit匹配的正则表达式。看起来很容易,但我的正则表达式让我失望。

5 个答案:

答案 0 :(得分:3)

格式有点不足,但这似乎有效:

class ButtonGhostScene: SKScene {
    var button: SKNode! = nil
    var ghost: SKSpriteNode! = nil

    override func didMove(to view: SKView) {
        button = SKSpriteNode(color: SKColor.redColor(), size: CGSize(width: 100, height: 44))
        button.position = CGPoint(x:self.size.width, y:self.size.height)

        ghost = SKSpriteNode(imageNamed: "Ghost1")
        ghost.size = CGSize(width: 50, height: 50)
        ghost.position = CGPoint(x: self.frame.width / 2 - Ghost.frame.width, y: self.frame.height / 2)
        ghost.physicsBody = SKPhysicsBody(circleOfRadius: Ghost.frame.height / 1.4)
        ghost.physicsBody?.categoryBitMask = PhysicsCatagory.Ghost
        ghost.physicsBody?.collisionBitMask = PhysicsCatagory.Ground | PhysicsCatagory.Wall
        ghost.physicsBody?.contactTestBitMask = PhysicsCatagory.Ground | PhysicsCatagory.Wall | PhysicsCatagory.Score
        ghost.physicsBody?.affectedByGravity = false
        ghost.physicsBody?.isDynamic = true
        ghost.zPosition = 2

        self.addChild(ghost)
        self.addChild(button)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        // Loop over all the touches in this event
        for touch: AnyObject in touches {
            // Get the location of the touch in this scene
            let location = touch.location(in: self)
            // Check if the location of the touch is within the button's bounds
            if button.containsPoint(location) {
                ghost.texture = SKTexture(imageNamed:"Ghost2")
            }
        }
    }
}

来自docs

  

图像名称由斜杠分隔的名称组件组成,可选择以注册表主机名为前缀。主机名必须符合标准DNS规则,但可能不包含下划线。如果存在主机名,则可以选择后跟以下格式的端口号:8080。如果不存在,该命令默认使用位于registry-1.docker.io的Docker的公共注册表。名称组件可能包含小写字符,数字和分隔符。分隔符定义为句点,一个或两个下划线,或一个或多个破折号。名称组件不能以分隔符开头或结尾。

     

标记名称可能包含小写和大写字符,数字,下划线,句点和短划线。标签名称不能以句点或短划线开头,最多可包含128个字符。

测试是here

答案 1 :(得分:2)

您可以尝试:

(?:[a-z]+/)?([a-z]+)(?::[0-9]+)?

但您需要阅读规范以将a-z和0-9替换为所有可能的字符。

或者,此正则表达式将捕获容器名称,而不考虑/:以外的规范:

(?:.+/)?([^:]+)(?::.+)?

样本数据和测试

def s = [
    'registry.example.com/org/image-name',
    'registry/org/image-name',
    'registry/image-name',
    'image-name',
    'registry.example.com/org/image-name:version',
    'registry/org/image-name:version',
    'registry/image-name:version',
    'image-name:version',
]

s.forEach {
    def image = (s =~ "(?:.+/)?([^:]+)(?::.+)?")[0][1]
    println image
    assert image == 'image-name'
}

将输出:

image-name
image-name
image-name
image-name
image-name
image-name
image-name
image-name

答案 2 :(得分:1)

该问题还有另一种解决方案,其中包含所有品种,并且不使用提前行。

// image/tag:v1.0.0
// 123.123.123.123:123/image/tag:v1.0.0
// your-domain.com/image/tag
// your-domain.com/image/tag:v1.1.1-patch1
// image/tag
// image
// image:v1.1.1-patch
// ubuntu@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2
// etc...
const dockerImageVerify = "^(([a-z0-9]|[a-z0-9][a-z0-9\\-]*[a-z0-9])\\.)*([a-z0-9]|[a-z0-9][a-z0-9\\-]*[a-z0-9])(:[0-9]+\\/)?(?:[0-9a-z-]+[/@])(?:([0-9a-z-]+))[/@]?(?:([0-9a-z-]+))?(?::[a-z0-9\\.-]+)?$"

这涵盖了所有情况。

答案 3 :(得分:0)

我认为这涵盖了所有内容:

const ipRegexStr = '((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))';
const hostnameRegexStr = '((([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9]))';
const tagNameRegexStr = '([a-z0-9](\-*[a-z0-9])*)';
const tagVersionRegexStr = '([a-z0-9\_]([\-\.\_a-z0-9])*)';
const dockerRepoTagRegexStr = `^(${ipRegexStr}|${hostnameRegexStr}/)${tagNameRegexStr}(:${tagVersionRegexStr})?$`;

const dockerTagRegex = new RegExp(dockerRepoTagRegexStr);

console.log(dockerTagRegex.test('11.com/0-2:122--')); //true
console.log(dockerTagRegex.test('192.168.1.2/0---2:232-323-d-')); //true
console.log(dockerTagRegex.test('-0-2')); //false
console.log(dockerTagRegex.test('0-2-')); //false
console.log(dockerTagRegex.test('0-2:-23423')); //false

答案 4 :(得分:0)

这是受上述答案启发的又一次迭代。理想情况下,docker-compose 文件中应该有一个长格式,这样我们就不必分解它们。我也不确定我是否以正确的方式命名(注册表/图像/标签:标签)。我无法保证它遵循规范的程度,是否太严格或不够严格等等。YMMV。

  • 这是 Python(不是 JS),因此可能不适用于 DevOps 工具领域中的大多数
  • 允许图像标记标签 (${VAR_NAME}) 的严格大写变量名称
  • 强制执行一些合理的字符限制,但我没有研究规范允许的内容
  • 此代码块处于 VERBOSE 模式,需要包含在 re.compile("<block>", re.X) 中以允许删除注释/空格
# FIRST we have the registry/image/tag:label format
(?:^
    # registry
    (?:(?P<registry>
        (?:
        # IPv4
        (?P<reg_ip>(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))
        |
        # domain
        (?P<reg_domain>(?:(?:[a-zA-Z][a-zA-Z0-9\-]{,48}[a-zA-Z0-9])\.){,4}(?:[A-Za-z]|[A-Za-z][A-Za-z0-9\-]{,48}[A-Za-z0-9]))
        |
        # hostname
        (?P<reg_host>([A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9]))
        )
        # port
        (?P<reg_port>:[0-9]+)?
    )
    # registry is optional, and not greedy
    /)??
    (?P<image>[0-9a-z_-]{1,40})
    (?:/
    (?P<tag>[0-9a-z_-]{1,40})
    )?
    # label can be a literal or a variable
    (?::
    (?P<label>[a-z0-9][a-z0-9._-]{1,38}[a-z0-9]|\${[A-Z][A-Z0-9_]{,38}[A-Z0-9]})
    )?
# next we have the digest format
$)|(?:^
(?P<user>[a-zA-Z]\w{,25})
@sha256:
(?P<hashcode>[0-9a-f]{64})
$)

这是在更改部分解析图像字符串后呈现新图像字符串的代码提示:

def __str__(self):
    if self.image:
        image_tag = '/'.join(filter(None, (self.image, self.tag)))
        imag_tag_label = ':'.join(filter(None, (image_tag, self.label)))
        return '/'.join(filter(None, (self.registry, imag_tag_label)))
    return f'{self.user}@sha256:{self.hashcode}'