【问题标题】:How to Compare Two String With Optional Characters?如何比较两个字符串与可选字符?
【发布时间】:2019-10-05 14:29:35
【问题描述】:

假设我们有一个函数(在 Django || python 中)比较两个字符串,一个是正确答案,另一个是学生回答的字符串。

correct = '(an) apple (device)'
student_answerd = 'apple device'

我想用正确的字符串检查 student_answered,但括号是可选的,这意味着以下所有 student_answered 都是正确的:

    case 1: an apple device
    case 2: an apple
    case 3: apple device
    case 4: apple

注意:我们没有对所有问题都使用相同的正确格式,这意味着括号的位置不同,例如我们可能只有一个或多个括号。

【问题讨论】:

  • 到目前为止你有什么尝试?
  • 您可以为此使用正则表达式。那么正则表达式可能看起来像'(an)? ?apple?(device)?',它将与学生的答案相匹配。
  • @WillemVanOnsem 你能写出伪代码吗?

标签: python regex django string-comparison regex-greedy


【解决方案1】:

也许,在这里我们可以忽略 () 并看到所需的输出:

(.*?)(?:[()]|)

正则表达式

如果这不是您想要的表达方式,您可以在regex101.com 中修改/更改您的表达方式。

正则表达式电路

你也可以在jex.im中可视化你的表情:

JavaScript 演示

const regex = /(.*?)(?:[()]|)/gm;
const str = `(an) apple (device)
apple device`;
const subst = `$1`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log('Substitution result: ', result);

Python 测试

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"(.*?)(?:[()]|)"

test_str = ("(an) apple (device)\n"
    "apple device")

subst = "\\1"

# You can manually specify the number of replacements by changing the 4th argument
result = re.sub(regex, subst, test_str, 0, re.MULTILINE)

if result:
    print (result)

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.

正则表达式

如果您希望逐字检查正确答案,您可能需要逐字逐句进行。也许,这个表达式会起作用:

^((an|one)?(\s?)([aple]+)?(\s?)([devic]+)?)$

Python 代码

您可以简单地为匹配和不匹配添加if

# -*- coding: UTF-8 -*-
import re

string = "an apple device"
expression = r'^((an|one)?(\s?)([aple]+)?(\s?)([devic]+)?)$'
match = re.search(expression, string)
if match:
    print("YAAAY! \"" + match.group(1) + "\" is a match ??? ")
else: 
    print('? Sorry! No matches!')

输出

YAAAY! "an apple device" is a match ???

完整匹配和组的 JavaScript 演示

const regex = /^((an|one)?(\s?)([aple]+)?(\s?)([devic]+)?)$/gm;
const str = `an apple device
an apple
apple device
apple
one apple
one appl device
two apple deive
on apple device
a apple device`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

然后,您可以将任何其他您希望的字符添加到列表中,例如括号:

^(((one|an)+)?(\s?)([aple()]+)?(\s?)([()devic]+)?)$ 

这也会传递一些拼写错误的单词,我猜这是需要的。如果没有,您可以简单地删除 [] 并使用具有逻辑 OR 的捕获组:

(apple|orange|banana)?

【讨论】:

  • 这很好,但我需要一些代码来返回真或假,例如,如果学生写“两个 Apple 设备”,我想得到错误的比较结果。注意:所有字符都已经转换为 .lower()
  • 错过理解的伙伴忘记了最后一个示例,考虑我们有一个字符串,如 (a) hardhat(s) 括号是可选的,这意味着:一个安全帽是可以的,安全帽是可以的,一个安全帽是可以的,等等。 ..括号是可选的,保留是强制的。
【解决方案2】:
"apple" in student_answer #matches 'papple'

"apple" in student_answer.split() # doesn't match 'papple'

此外,您还可以更换常见的添加剂。

a = [',', 'an', ' ', 'device']
for i in a:
    student_answer = student_answer.replace(a, '')
student_answer == 'apple'

【讨论】:

    猜你喜欢
    • 2019-01-14
    • 2022-06-29
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2022-09-30
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    相关资源
    最近更新 更多