0

我有一个植物学名的查找表。我想使用此查找表来验证我有数据输入人员输入数据的其他表。有时他们会弄错这些学名的格式,所以我正在编写一个脚本来尝试标记错误。

有一种非常具体的方式来格式化每个名称。例如'Sonchus arvensis L.' 特别需要将 Sonchus 中的 S 以及末尾的 L 大写。我有大约 1000 种不同的植物,每种植物的格式都不同。这里还有几个例子:

  • Linaria dalmatica (L.) 磨坊。
  • Knautia arvensis (L.) Coult。
  • Alliaria petiolata (M. Bieb.) Cavara & Grande
  • Berteroa incana (L.) DC。
  • Aegilops cylindrica Host

正如您所看到的,所有这些字符串的格式都非常不同(例如,有些字母大写,有些不是,有时还有括号、和号、句点等)

我的问题是,有没有办法动态读取查找表中每个字符串的格式,以便我可以将其与数据输入人员输入的值进行比较,以确保其格式正确?在下面的脚本中,我测试(第一个 elif)以查看该值是否在查找表中,方法是通过将所有值大写以使匹配工作,无论格式如何。在下一个测试(第二个 elif)中,我可以通过与查找表的值进行比较来对测试格式进行排序。这将根据格式返回不匹配的记录,但并没有具体告诉您为什么返回不匹配的记录。

我认为要做的是,读取查找表中的字符串值并以某种方式动态读取每个字符串的格式,以便我可以明确识别错误(即字母应该大写,而不是大写)

到目前为止,我的代码片段如下所示:

        # Determine if the field heaidng is in a list I built earlier
        if "SCIENTIFIC_NAME" in fieldnames:
            # First, Test to see if record is empty
            if not row.SCIENTIFIC_NAME:
                weedPLineErrors.append("SCIENTIFIC_NAME record is empty")
            # Second, Test to see if value is in the lookup table, regardless of formatting.
            elif row.SCIENTIFIC_NAME.upper() not in [x.upper() for x in weedScientificTableList]:
                weedPLineErrors.append("COMMON_NAME (" + row.SCIENTIFIC_NAME + ")" + " is not in the domain table")
            # Third, if the second test is satisfied, we know the value is in the lookup table. We can then test the lookup table again, without capitalizing everything to see if there is an exact match to account for formatting.
            elif row.SCIENTIFIC_NAME not in weedScientificTableList:
                weedPLineErrors.append("COMMON_NAME (" + row.SCIENTIFIC_NAME + ")" + " is not formatted properly")                        
            else:
                pass

我希望我的问题足够清楚。我查看了字符串模板,但我不认为它做我想做的事......至少不是动态的。如果有人能给我指出一个更好的方向,我会全神贯注……但也许我可以出去吃午饭了。

谢谢,迈克

4

2 回答 2

1

要解决标点符号问题,您可以使用正则表达式。

>>> import re
>>> def tokenize(s):
...     return re.split('[^A-Za-z]+', s) # Split by anything that isn't a letter
...
>>> tokens = tokenize('Alliaria petiolata (M. Bieb.) Cavara & Grande')
>>> tokens
['Alliaria', 'petiolata', 'M', 'Bieb', 'Cavara', 'Grande']

要解决大小写问题,您可以使用

>>> tokens = [s.lower() for s in tokens]

从那里,您可以以标准化格式重写条目,例如

>>> import string
>>> ## I'm not sure exactly what format  you're looking for
>>> first, second, third = [string.capitalize(s) for s in tokens[:3]]
>>> "%s %s (%s)" % (first, second, third)
'Alliaria Petiolata (M)'

这可能不是您想要的确切格式,但也许这会让您朝着正确的方向前进。

于 2013-06-18T20:22:52.410 回答
0

您可以从查找表中构建名称字典。假设您将名称存储在列表中(称为正确列表),您可以编写一个函数来删除所有格式,并可能降低或大写大小写并将结果存储在字典中。例如以下是构建字典的示例代码


def removeFormatting(name):
    name = name.replace("(", "").replace(")", "")
    name = name.replace(".", "")
    ...
    return name.lower()

formattingDict = dict([(removeFormatting(i), i) for i in correctList])

现在您可以比较数据输入人员输入的字符串。假设它在一个名为 inputList 的列表中。


for name in inputList:
    unformattedName = removeFormatting(name)
    lookedUpName = formattingDict.get(unformattedName, "")
    if not lookedUpName:
        print "Spelling mistake:", name
    elif lookedUpName != name:
        print "Formatting error"
        print differences(name, lookedUpName)

差异函数可以填充一些规则,如括号、“.”等


def differences(inputName, lookedUpName):
    mismatches = []
    # Check for brackets
    if "(" in lookedUpName:
        if "(" not in inputName:
            mismatches.append("Bracket missing")
    ...
    # Add more rules
    return mismatches

这有点回答你的问题吗?

于 2013-06-18T20:24:45.563 回答