Exemplo n.º 1
0
                    memberNsName = unionNode.qName2NsName(memberType, 1)
                    self._checkBaseType(unionNode, memberNsName,
                                        self.xsdTypeDict)
                    if self.xsdTypeDict.has_key(memberNsName):
                        if self.xsdTypeDict[memberNsName].getLocalName(
                        ) != "simpleType":
                            self._addError(
                                "MemberType %s must be a simple type!" %
                                (repr(memberNsName)), unionNode)

        patternNodes, dummy, dummy = self.inputRoot.getXPathList(
            ".//%(prefix)spattern" % vars())
        for patternNode in patternNodes:
            pattern = patternNode["value"]
            try:
                pattern = substituteSpecialEscChars(pattern)
                try:
                    test = re.compile(pattern)
                except Exception, errstr:
                    self._addError(str(errstr), patternNode)
                    self._addError(
                        "%s is not a valid regular expression!" %
                        (repr(patternNode["value"])), patternNode)
            except SyntaxError, errInst:
                self._addError(repr(errInst[0]), patternNode)

    ########################################
    # additional checks for keyrefs
    #
    def _checkIdentityConstraintsSecondLevel(self):
        identityConstraintNodes, dummy, dummy = self.inputRoot.getXPathList(
Exemplo n.º 2
0
                        break
                else:
                    self._addError("Union must not be empty!", unionNode)
            else:
                for memberType in string.split(unionNode["memberTypes"]):
                    memberNsName = unionNode.qName2NsName(memberType, 1)
                    self._checkBaseType(unionNode, memberNsName, self.xsdTypeDict)
                    if self.xsdTypeDict.has_key(memberNsName):
                        if self.xsdTypeDict[memberNsName].getLocalName() != "simpleType":
                            self._addError("MemberType %s must be a simple type!" % (repr(memberNsName)), unionNode)

        patternNodes, dummy, dummy = self.inputRoot.getXPathList(".//%(prefix)spattern" % vars())
        for patternNode in patternNodes:
            pattern = patternNode["value"]
            try:
                pattern = substituteSpecialEscChars(pattern)
                try:
                    test = re.compile(pattern)
                except Exception, errstr:
                    self._addError(str(errstr), patternNode)
                    self._addError("%s is not a valid regular expression!" % (repr(patternNode["value"])), patternNode)
            except SyntaxError, errInst:
                self._addError(repr(errInst[0]), patternNode)

    ########################################
    # additional checks for keyrefs
    #
    def _checkIdentityConstraintsSecondLevel(self):
        identityConstraintNodes, dummy, dummy = self.inputRoot.getXPathList(".//%sunique" % (self.inputNsPrefixString))
        for identityConstraintNode in identityConstraintNodes:
            # check for unique ID
Exemplo n.º 3
0
    def _checkRestrictionTag (self, inputNode, xsdElement, attrName, attributeValue, returnDict, idCheck):
        savedAttrValue = attributeValue
        # first check against base type
        self.checkBaseType (inputNode, xsdElement, attrName, attributeValue, returnDict, idCheck)

        minExcl = xsdElement.getFirstChildNS(self.xsdNsURI, "minExclusive")
        minIncl = xsdElement.getFirstChildNS(self.xsdNsURI, "minInclusive")
        maxExcl = xsdElement.getFirstChildNS(self.xsdNsURI, "maxExclusive")
        maxIncl = xsdElement.getFirstChildNS(self.xsdNsURI, "maxInclusive")

        if minExcl != None:
            minExclReturnDict = {"BaseTypes":[], "primitiveType":None}
            minExclValue = minExcl.getAttribute("value")
            self.checkBaseType (inputNode, xsdElement, attrName, minExclValue, minExclReturnDict, idCheck=0)
            if returnDict.has_key("orderedValue") and minExclReturnDict.has_key("orderedValue"):
                if returnDict["orderedValue"] <= minExclReturnDict["orderedValue"]:
                    raise SimpleTypeError ("Value of %s (%s) is <= minExclusive (%s)" %(repr(attrName), repr(attributeValue), repr(minExclValue)))
        elif minIncl != None:
            minInclReturnDict = {"BaseTypes":[], "primitiveType":None}
            minInclValue = minIncl.getAttribute("value")
            self.checkBaseType (inputNode, xsdElement, attrName, minInclValue, minInclReturnDict, idCheck=0)
            if returnDict.has_key("orderedValue") and minInclReturnDict.has_key("orderedValue"):
                if returnDict["orderedValue"] < minInclReturnDict["orderedValue"]:
                    raise SimpleTypeError ("Value of %s (%s) is < minInclusive (%s)" %(repr(attrName), repr(attributeValue), repr(minInclValue)))
        if maxExcl != None:
            maxExclReturnDict = {"BaseTypes":[], "primitiveType":None}
            maxExclValue = maxExcl.getAttribute("value")
            self.checkBaseType (inputNode, xsdElement, attrName, maxExclValue, maxExclReturnDict, idCheck=0)
            if returnDict.has_key("orderedValue") and maxExclReturnDict.has_key("orderedValue"):
                if returnDict["orderedValue"] >= maxExclReturnDict["orderedValue"]:
                    raise SimpleTypeError ("Value of %s (%s) is >= maxExclusive (%s)" %(repr(attrName), repr(attributeValue), repr(maxExclValue)))
        elif maxIncl != None:
            maxInclReturnDict = {"BaseTypes":[], "primitiveType":None}
            maxInclValue = maxIncl.getAttribute("value")
            self.checkBaseType (inputNode, xsdElement, attrName, maxInclValue, maxInclReturnDict, idCheck=0)
            if returnDict.has_key("orderedValue") and maxInclReturnDict.has_key("orderedValue"):
                if returnDict["orderedValue"] > maxInclReturnDict["orderedValue"]:
                    raise SimpleTypeError ("Value of %s (%s) is > maxInclusive (%s)" %(repr(attrName), repr(attributeValue), repr(maxInclValue)))

        totalDigitsNode = xsdElement.getFirstChildNS(self.xsdNsURI, "totalDigits")
        if totalDigitsNode != None:
            orderedValueStr = repr(returnDict["orderedValue"])
            digits = re.findall("\d" ,orderedValueStr)
            if digits[0] == "0" and len(digits) > 1:
                digits = digits[1:]
            totalDigitsValue = totalDigitsNode.getAttribute("value")
            if totalDigitsNode.getAttribute("fixed") == "true":
                if len(digits) != string.atoi(totalDigitsValue):
                    raise SimpleTypeError ("Total number of digits != %s for %s (%s)" %(repr(totalDigitsValue), repr(attrName), repr(attributeValue)))
            else:
                if len(digits) > string.atoi(totalDigitsValue):
                    raise SimpleTypeError ("Total number of digits > %s for %s (%s)" %(repr(totalDigitsValue), repr(attrName), repr(attributeValue)))

        fractionDigitsNode = xsdElement.getFirstChildNS(self.xsdNsURI, "fractionDigits")
        if fractionDigitsNode != None:
            orderedValueStr = repr(returnDict["orderedValue"])
            fractionDigitsValue = fractionDigitsNode.getAttribute("value")
            result = re.search("(?P<intDigits>\d*)(?P<dot>\.)(?P<fracDigits>\d+)", orderedValueStr)
            if result != None:
                numberOfFracDigits = len (result.group('fracDigits'))
            else:
                numberOfFracDigits = 0
            if fractionDigitsNode.getAttribute("fixed") == "true" and numberOfFracDigits != string.atoi(fractionDigitsValue):
                raise SimpleTypeError ("Fraction number of digits != %s for %s (%s)" %(repr(fractionDigitsValue), repr(attrName), repr(attributeValue)))
            elif numberOfFracDigits > string.atoi(fractionDigitsValue):
                raise SimpleTypeError ("Fraction number of digits > %s for %s (%s)" %(repr(fractionDigitsValue), repr(attrName), repr(attributeValue)))

        if returnDict.has_key("length"):
            lengthNode = xsdElement.getFirstChildNS(self.xsdNsURI, "length")
            if lengthNode != None:
                length = string.atoi(lengthNode.getAttribute("value"))
                if returnDict["length"] != length:
                    raise SimpleTypeError ("Length of %s (%s) must be %d!" %(repr(attrName), repr(attributeValue), length))
            minLengthNode = xsdElement.getFirstChildNS(self.xsdNsURI, "minLength")
            if minLengthNode != None:
                minLength = string.atoi(minLengthNode.getAttribute("value"))
                if returnDict["length"] < minLength:
                    raise SimpleTypeError ("Length of %s (%s) must be >= %d!" %(repr(attrName), repr(attributeValue), minLength))
            maxLengthNode = xsdElement.getFirstChildNS(self.xsdNsURI, "maxLength")
            if maxLengthNode != None:
                maxLength = string.atoi(maxLengthNode.getAttribute("value"))
                if returnDict["length"] > maxLength:
                    raise SimpleTypeError ("Length of %s (%s) must be <= %d!" %(repr(attrName), repr(attributeValue), maxLength))

        whiteSpace = xsdElement.getFirstChildNS(self.xsdNsURI, "whiteSpace")
        if whiteSpace != None:
            returnDict["wsAction"] = whiteSpace.getAttribute("value")
            if returnDict["wsAction"] == "replace":
                normalizedValue = normalizeString(attributeValue)
                if normalizedValue != attributeValue:
                    returnDict["adaptedAttrValue"] = normalizedValue
            elif returnDict["wsAction"] == "collapse":
                collapsedValue = collapseString(attributeValue)
                if collapsedValue != attributeValue:
                    returnDict["adaptedAttrValue"] = collapsedValue

        enumerationElementList = xsdElement.getChildrenNS(self.xsdNsURI, "enumeration")
        if enumerationElementList != []:
            if returnDict.has_key("orderedValue"):
                attributeValue = returnDict["orderedValue"]
            elif returnDict.has_key("adaptedAttrValue"):
                attributeValue = returnDict["adaptedAttrValue"]

            for enumeration in enumerationElementList:
                enumReturnDict = {"BaseTypes":[], "primitiveType":None}
                enumValue = enumeration["value"]
                self.checkBaseType (inputNode, xsdElement, attrName, enumValue, enumReturnDict, idCheck=0)
                if enumReturnDict.has_key("orderedValue"):
                    enumValue = enumReturnDict["orderedValue"]
                elif enumReturnDict.has_key("adaptedAttrValue"):
                    enumValue = enumReturnDict["adaptedAttrValue"]
                
                if enumValue == attributeValue:
                    break
            else:
                raise SimpleTypeError ("Enumeration value %s not allowed!" %repr(attributeValue))

        
        if returnDict.has_key("adaptedAttrValue"):
            attributeValue = returnDict["adaptedAttrValue"]

        patternMatch = 1
        notMatchedPatternList = []
        for patternNode in xsdElement.getChildrenNS(self.xsdNsURI, "pattern"):
            rePattern = patternNode.getAttribute("value")
            intRePattern = rePattern
            try:
                intRePattern = substituteSpecialEscChars (intRePattern)
            except SyntaxError, errInst:
                raise SimpleTypeError, str(errInst)
            patternMatch = self._matchesPattern (intRePattern, attributeValue)

            if patternMatch:
                break
            else:
                notMatchedPatternList.append(rePattern)
Exemplo n.º 4
0
            except SimpleTypeError, errstr:
                pass

        raise SimpleTypeError ("%s (%s) is no valid union member type!" %(repr(attrName), repr(attributeValue)))


###############################################################
#  Base type check functions
###############################################################

reDecimal      = re.compile("[+-]?[0-9]*\.?[0-9]+", re.U)
reInteger      = re.compile("[+-]?[0-9]+", re.U)
reDouble       = re.compile("([+-]?[0-9]*\.?[0-9]+([eE][+\-]?[0-9]+)?)|INF|-INF|NaN", re.U)
reHexBinary    = re.compile("([a-fA-F0-9]{2})*", re.U)
reBase64Binary = re.compile("(?P<validBits>[a-zA-Z0-9+/]*)={0,3}", re.U)
reQName        = re.compile(substituteSpecialEscChars("\i\c*"), re.U)
reDuration     = re.compile("-?P(?P<years>\d+Y)?(?P<months>\d+M)?(?P<days>\d+D)?(T(?P<hours>\d+H)?(?P<minutes>\d+M)?((?P<seconds>\d+)(?P<fracsec>\.\d+)?S)?)?", re.U)

reDateTime     = re.compile("(?P<date>\d{4}-\d{2}-\d{2})T(?P<time>\d{2}:\d{2}:\d{2}(\.\d+)?)(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reDate         = re.compile("\d{4}-\d{2}-\d{2}(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reTime         = re.compile("(?P<time>\d{2}:\d{2}:\d{2})(?P<fracsec>\.\d+)?(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reYearMonth    = re.compile("\d{4}-\d{2}(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reMonthDay     = re.compile("--\d{2}-\d{2}(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reYear         = re.compile("(?P<year>\d{1,4})(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reMonth        = re.compile("--\d{2}(--)?(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reDay          = re.compile("---\d{2}(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)


def _checkAnySimpleType (inputNode, simpleType, attributeValue, returnDict):
    # TODO: Nothing to check??
    returnDict["length"] = len(attributeValue)
Exemplo n.º 5
0
    def _checkRestrictionTag(self, inputNode, xsdElement, attrName,
                             attributeValue, returnDict, idCheck):
        savedAttrValue = attributeValue
        # first check against base type
        self.checkBaseType(inputNode, xsdElement, attrName, attributeValue,
                           returnDict, idCheck)

        minExcl = xsdElement.getFirstChildNS(self.xsdNsURI, "minExclusive")
        minIncl = xsdElement.getFirstChildNS(self.xsdNsURI, "minInclusive")
        maxExcl = xsdElement.getFirstChildNS(self.xsdNsURI, "maxExclusive")
        maxIncl = xsdElement.getFirstChildNS(self.xsdNsURI, "maxInclusive")

        if minExcl != None:
            minExclReturnDict = {"BaseTypes": [], "primitiveType": None}
            minExclValue = minExcl.getAttribute("value")
            self.checkBaseType(inputNode,
                               xsdElement,
                               attrName,
                               minExclValue,
                               minExclReturnDict,
                               idCheck=0)
            if returnDict.has_key(
                    "orderedValue") and minExclReturnDict.has_key(
                        "orderedValue"):
                if returnDict["orderedValue"] <= minExclReturnDict[
                        "orderedValue"]:
                    raise SimpleTypeError(
                        "Value of %s (%s) is <= minExclusive (%s)" %
                        (repr(attrName), repr(attributeValue),
                         repr(minExclValue)))
        elif minIncl != None:
            minInclReturnDict = {"BaseTypes": [], "primitiveType": None}
            minInclValue = minIncl.getAttribute("value")
            self.checkBaseType(inputNode,
                               xsdElement,
                               attrName,
                               minInclValue,
                               minInclReturnDict,
                               idCheck=0)
            if returnDict.has_key(
                    "orderedValue") and minInclReturnDict.has_key(
                        "orderedValue"):
                if returnDict["orderedValue"] < minInclReturnDict[
                        "orderedValue"]:
                    raise SimpleTypeError(
                        "Value of %s (%s) is < minInclusive (%s)" %
                        (repr(attrName), repr(attributeValue),
                         repr(minInclValue)))
        if maxExcl != None:
            maxExclReturnDict = {"BaseTypes": [], "primitiveType": None}
            maxExclValue = maxExcl.getAttribute("value")
            self.checkBaseType(inputNode,
                               xsdElement,
                               attrName,
                               maxExclValue,
                               maxExclReturnDict,
                               idCheck=0)
            if returnDict.has_key(
                    "orderedValue") and maxExclReturnDict.has_key(
                        "orderedValue"):
                if returnDict["orderedValue"] >= maxExclReturnDict[
                        "orderedValue"]:
                    raise SimpleTypeError(
                        "Value of %s (%s) is >= maxExclusive (%s)" %
                        (repr(attrName), repr(attributeValue),
                         repr(maxExclValue)))
        elif maxIncl != None:
            maxInclReturnDict = {"BaseTypes": [], "primitiveType": None}
            maxInclValue = maxIncl.getAttribute("value")
            self.checkBaseType(inputNode,
                               xsdElement,
                               attrName,
                               maxInclValue,
                               maxInclReturnDict,
                               idCheck=0)
            if returnDict.has_key(
                    "orderedValue") and maxInclReturnDict.has_key(
                        "orderedValue"):
                if returnDict["orderedValue"] > maxInclReturnDict[
                        "orderedValue"]:
                    raise SimpleTypeError(
                        "Value of %s (%s) is > maxInclusive (%s)" %
                        (repr(attrName), repr(attributeValue),
                         repr(maxInclValue)))

        totalDigitsNode = xsdElement.getFirstChildNS(self.xsdNsURI,
                                                     "totalDigits")
        if totalDigitsNode != None:
            orderedValueStr = repr(returnDict["orderedValue"])
            digits = re.findall("\d", orderedValueStr)
            if digits[0] == "0" and len(digits) > 1:
                digits = digits[1:]
            totalDigitsValue = totalDigitsNode.getAttribute("value")
            if totalDigitsNode.getAttribute("fixed") == "true":
                if len(digits) != string.atoi(totalDigitsValue):
                    raise SimpleTypeError(
                        "Total number of digits != %s for %s (%s)" %
                        (repr(totalDigitsValue), repr(attrName),
                         repr(attributeValue)))
            else:
                if len(digits) > string.atoi(totalDigitsValue):
                    raise SimpleTypeError(
                        "Total number of digits > %s for %s (%s)" %
                        (repr(totalDigitsValue), repr(attrName),
                         repr(attributeValue)))

        fractionDigitsNode = xsdElement.getFirstChildNS(
            self.xsdNsURI, "fractionDigits")
        if fractionDigitsNode != None:
            orderedValueStr = repr(returnDict["orderedValue"])
            fractionDigitsValue = fractionDigitsNode.getAttribute("value")
            result = re.search(
                "(?P<intDigits>\d*)(?P<dot>\.)(?P<fracDigits>\d+)",
                orderedValueStr)
            if result != None:
                numberOfFracDigits = len(result.group('fracDigits'))
            else:
                numberOfFracDigits = 0
            if fractionDigitsNode.getAttribute(
                    "fixed") == "true" and numberOfFracDigits != string.atoi(
                        fractionDigitsValue):
                raise SimpleTypeError(
                    "Fraction number of digits != %s for %s (%s)" %
                    (repr(fractionDigitsValue), repr(attrName),
                     repr(attributeValue)))
            elif numberOfFracDigits > string.atoi(fractionDigitsValue):
                raise SimpleTypeError(
                    "Fraction number of digits > %s for %s (%s)" %
                    (repr(fractionDigitsValue), repr(attrName),
                     repr(attributeValue)))

        if returnDict.has_key("length"):
            lengthNode = xsdElement.getFirstChildNS(self.xsdNsURI, "length")
            if lengthNode != None:
                length = string.atoi(lengthNode.getAttribute("value"))
                if returnDict["length"] != length:
                    raise SimpleTypeError(
                        "Length of %s (%s) must be %d!" %
                        (repr(attrName), repr(attributeValue), length))
            minLengthNode = xsdElement.getFirstChildNS(self.xsdNsURI,
                                                       "minLength")
            if minLengthNode != None:
                minLength = string.atoi(minLengthNode.getAttribute("value"))
                if returnDict["length"] < minLength:
                    raise SimpleTypeError(
                        "Length of %s (%s) must be >= %d!" %
                        (repr(attrName), repr(attributeValue), minLength))
            maxLengthNode = xsdElement.getFirstChildNS(self.xsdNsURI,
                                                       "maxLength")
            if maxLengthNode != None:
                maxLength = string.atoi(maxLengthNode.getAttribute("value"))
                if returnDict["length"] > maxLength:
                    raise SimpleTypeError(
                        "Length of %s (%s) must be <= %d!" %
                        (repr(attrName), repr(attributeValue), maxLength))

        whiteSpace = xsdElement.getFirstChildNS(self.xsdNsURI, "whiteSpace")
        if whiteSpace != None:
            returnDict["wsAction"] = whiteSpace.getAttribute("value")
            if returnDict["wsAction"] == "replace":
                normalizedValue = normalizeString(attributeValue)
                if normalizedValue != attributeValue:
                    returnDict["adaptedAttrValue"] = normalizedValue
            elif returnDict["wsAction"] == "collapse":
                collapsedValue = collapseString(attributeValue)
                if collapsedValue != attributeValue:
                    returnDict["adaptedAttrValue"] = collapsedValue

        enumerationElementList = xsdElement.getChildrenNS(
            self.xsdNsURI, "enumeration")
        if enumerationElementList != []:
            if returnDict.has_key("orderedValue"):
                attributeValue = returnDict["orderedValue"]
            elif returnDict.has_key("adaptedAttrValue"):
                attributeValue = returnDict["adaptedAttrValue"]

            for enumeration in enumerationElementList:
                enumReturnDict = {"BaseTypes": [], "primitiveType": None}
                enumValue = enumeration["value"]
                self.checkBaseType(inputNode,
                                   xsdElement,
                                   attrName,
                                   enumValue,
                                   enumReturnDict,
                                   idCheck=0)
                if enumReturnDict.has_key("orderedValue"):
                    enumValue = enumReturnDict["orderedValue"]
                elif enumReturnDict.has_key("adaptedAttrValue"):
                    enumValue = enumReturnDict["adaptedAttrValue"]

                if enumValue == attributeValue:
                    break
            else:
                raise SimpleTypeError("Enumeration value %s not allowed!" %
                                      repr(attributeValue))

        if returnDict.has_key("adaptedAttrValue"):
            attributeValue = returnDict["adaptedAttrValue"]

        patternMatch = 1
        notMatchedPatternList = []
        for patternNode in xsdElement.getChildrenNS(self.xsdNsURI, "pattern"):
            rePattern = patternNode.getAttribute("value")
            intRePattern = rePattern
            try:
                intRePattern = substituteSpecialEscChars(intRePattern)
            except SyntaxError, errInst:
                raise SimpleTypeError, str(errInst)
            patternMatch = self._matchesPattern(intRePattern, attributeValue)

            if patternMatch:
                break
            else:
                notMatchedPatternList.append(rePattern)
Exemplo n.º 6
0
        raise SimpleTypeError("%s (%s) is no valid union member type!" %
                              (repr(attrName), repr(attributeValue)))


###############################################################
#  Base type check functions
###############################################################

reDecimal = re.compile("[+-]?[0-9]*\.?[0-9]+", re.U)
reInteger = re.compile("[+-]?[0-9]+", re.U)
reDouble = re.compile("([+-]?[0-9]*\.?[0-9]+([eE][+\-]?[0-9]+)?)|INF|-INF|NaN",
                      re.U)
reHexBinary = re.compile("([a-fA-F0-9]{2})*", re.U)
reBase64Binary = re.compile("(?P<validBits>[a-zA-Z0-9+/]*)={0,3}", re.U)
reQName = re.compile(substituteSpecialEscChars("\i\c*"), re.U)
reDuration = re.compile(
    "-?P(?P<years>\d+Y)?(?P<months>\d+M)?(?P<days>\d+D)?(T(?P<hours>\d+H)?(?P<minutes>\d+M)?((?P<seconds>\d+)(?P<fracsec>\.\d+)?S)?)?",
    re.U)

reDateTime = re.compile(
    "(?P<date>\d{4}-\d{2}-\d{2})T(?P<time>\d{2}:\d{2}:\d{2}(\.\d+)?)(?P<offset>Z|[+-]\d{2}:\d{2})?",
    re.U)
reDate = re.compile("\d{4}-\d{2}-\d{2}(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reTime = re.compile(
    "(?P<time>\d{2}:\d{2}:\d{2})(?P<fracsec>\.\d+)?(?P<offset>Z|[+-]\d{2}:\d{2})?",
    re.U)
reYearMonth = re.compile("\d{4}-\d{2}(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reMonthDay = re.compile("--\d{2}-\d{2}(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reYear = re.compile("(?P<year>\d{1,4})(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reMonth = re.compile("--\d{2}(--)?(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)