def matchClosed(row):
    match = re.match('[msvt]\d+(\(-?\d+,-?\d+\))+$', row['Name'])

    if not match:
        return None
    
    degree = safeDictLookup(row,"InvariantTraceFieldDegree", 1000)
    if not degree:
        degree = 1000

    return (row["Tetrahedra"], degree, row["Name"])
def matchLink(row):
    crossings = None
    components = None
    index = None

    preference = 1000

    matchRolfsen = re.match("(\d+)(\^(\d+))?_(\d+)", row['Name'])
    if matchRolfsen:
        crossings, s, components, index = matchRolfsen.groups()
        index = int(index)
        preference = 0

    matchKnot = re.match("(\d+)([an])(\d+)", row['Name'])
    if matchKnot:
        crossings, alt, index = matchKnot.groups()
        index = int(index)
        components = 1
        if alt == "a":
            preference = 1
        else:
            preference = 2

    matchMorwen = re.match("(\d+)(\^(\d+))?_(DT\[\w+\])", row['Name'])
    if matchMorwen:
        crossings, dum, components, index = matchMorwen.groups()
        preference = 3
    
    if not crossings:
        return None

    crossings = int(crossings)
    if components:
        components = int(components)
    components = 1

    degree = safeDictLookup(row, "InvariantTraceFieldDegree", 1000)
    if not degree:
        degree = 1000
    
    return (components, crossings, degree, row["Tetrahedra"], index, preference)