【问题标题】:Text transformation: Adding text according to previous occurrence文本转换:根据上一次出现添加文本
【发布时间】:2016-01-18 17:41:18
【问题描述】:

我有一个包含多个问题的文本,格式如下:

Q1

Question text 1?

1. Answer A
2. Answer B (+1p)
3. Answer C
4. Answer D

Q2

Question Text 2?

1. Answer A (+1p)
2. Answer B
3. Answer C (+1p)
4. Answer D 

Q3

Question Text 3

1. Answer A
2. Answer B
3. Answer C (+1p)

正确答案标有 (+1p)。 我想重新格式化它,以便在如下新行中说明正确的答案:

Q1

Question text 1?

1. Answer A
2. Answer B
3. Answer C
4. Answer D
Answer: B

Q2

Question Text 2?

1. Answer A
2. Answer B
3. Answer C
4. Answer D 
Answer: A, C

Q3

Question Text 3

1. Answer A
2. Answer B
3. Answer C
Answer: C

这甚至可以在 Notepad++ 中完成吗?

【问题讨论】:

  • 您需要一些编程语言(PHP、Python 等)来获取输入并根据正则表达式匹配运行回调函数。 Notepad++ 只是让你简单地替换匹配的文本,没有额外的逻辑。又名:可能,但不在那个程序中。

标签: php regex algorithm notepad++


【解决方案1】:

正则表达式的救命稻草:

我们需要一个两步的方法,

  1. 追加Answer:

    • 查找内容: ((\R\d\.\h+Answer\h+[A-Z]+\h?(\(\+1p\))?)+)
    • 替换为: \1\r\nAnswer:
    • 检查正则表达式
    • 点击替换全部替换
  2. 现在我们收集答案:

    • 查找内容: Answer ([A-Z])\h\(\+1p\)(.*?Answer: [A-Z ]*)
    • 替换为: Answer \1\2\1
    • 检查正则表达式
    • 检查。匹配换行符
    • 点击替换全部替换。继续点击,一个块中有多个答案的案例需要与块中的答案一样多的全部替换。观察对话框状态栏中的消息。完成后它会告诉你。

在第一步中,查找尝试匹配完整的答案块并将其捕获到\1。替换只是在块之后添加一行。

第二步尝试(对于每个块)捕获从第一个 (+1p)Answer: 的行。发现(+1p)没有 cpatured。答案的 answer char 被捕获在 \1 中,直到 Answer: 行的以下答案被捕获在 \2 中,我们将 answer char 附加到 '\ 1'到'答案:'行。 (只需进行一些查找,查看匹配的内容,然后进行一些替换以查看它如何与具有多个标记答案的块一起使用。您可以撤消以重播替换。)

【讨论】:

  • 感谢 Lars 的详细解答!不幸的是,您的解决方案仅适用于这个给定的示例。这只是问题的模板。实际上会有一个实际的问题文本和答案选项。
【解决方案2】:

有时一个问题会让您在 SO 上感到兴奋(又名 这可以通过某种方式完成...)
到目前为止,您可能已经得出结论,对于像 Notepad++ 这样的编辑器来说,这并不是一件容易的事(如果不是不可能的话),所以我考虑了一种编程语言的解决方案(在我的例子中是 PHP正则表达式的帮助)并想在这里展示它:

解释:

代码基本上做了以下步骤:

  1. 查找问题块 - 这些是以数字和点开头的行块,在每个站点上被空行包围 - 并将它们的位置保存在原始字符串中。
  2. 在这些行中,尝试找到标记的答案(模式(+1p)
  3. 用可能的答案创建一个新字符串
  4. 答案字符串(Answer: ...)需要插入的位置可以通过下式计算:
    (original offset) + strlen(original string) + strlen(answer_string)

代码:

<?php

$string = 'your original string here';

$regex_questions = '~(?ms)(?:^$\R)(?P<answers>(?:^\d\. Answer [A-E].*?\R)+?)(?:^$\R)(?-ms)~';
# does what is described in point 1.)
preg_match_all($regex_questions, $string, $questions, PREG_OFFSET_CAPTURE);

$regex_answers = '~(?m)^(?:\d\. Answer (?<choice>[A-E]).*?\(\+1p\))$~';
# point 2.)
$offset = 0;

# loops over the questions
foreach ($questions["answers"] as $question) {
    preg_match_all($regex_answers, $question[0], $answers);
    $answer = "Answer: " . implode(',', $answers["choice"]) ."\n";
    # point 3.)

    $position = $offset + $question[1] + strlen($question[0]);
    # point 4.)

    $string = substr_replace($string, $answer, $position, 0);
    $offset += strlen($answer);
}
echo $string;
# After every code block there's a string with the appropiate answers
?>

演示:

查找online demo on ideone

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-14
    • 1970-01-01
    • 2022-01-03
    • 2012-12-15
    • 2021-01-27
    • 2015-08-10
    • 1970-01-01
    • 2020-03-18
    相关资源
    最近更新 更多