正则表达式捕获并包装大纲格式化文本

时间:2017-04-19 15:48:24

标签: regex

我的源文本不是特别干净或格式正确但我需要找到文本并在标记中换行。文字采用大纲格式。

1. becomes a <h1> tag
A. becomes a <h2> tag
(1) becomes a <h3> tag
and so on...

以下是来源的一些例子。

  
      
  1. 准备测试A.打开门。 B.打开灯。
  2.   

期望的结果是

<h1>1. PREPARE FOR TEST</h1>
<h2>A. Open the door.</h2>
<h2>B. Turn on the light.</h2>

不幸的是,文本可能是同一行,也可能是多行,甚至在大纲编号和文本之间有不同的空格数。另一个例子

  

(1)如果OAT高于&gt;检查空气入口和出气阀是否打开。 53.6华氏度,如果OAT低于

则关闭      

48.2度。

在这种情况下,所需的结果将是

<h3>(1) Check skin air inlet and skin air outlet valves are shown open if temperature is above 53.6 deg F., or closed if temperature is below 48.2 deg F.</h3>

我的问题是

  1. 如何查找与大纲级别关联的整行文本,即1.,A。,(1)等。
  2. 如何使用适当的标记包装该文本。
  3. 我对正则表达式并不是特别强大,我已经能够完成这个项目所需的一些简单的事情,但这让我有点难过。这是我以前试图找到的H1行,但正如任何知道正则表达式的人都可以清楚地看到的那样,这不会超过第一个单词。

      

    \ d {1,3}。\ S + [A-Z] {2,}

    我目前正在使用Python,但对PHP更好,如果需要可以转移到那里,但仍然可能因为我更擅长PHP而不是Python。

    谢谢。

2 个答案:

答案 0 :(得分:1)

由于每个正则表达式都需要不同的替换,因此您需要依次应用每个正则表达式。假设您希望匹配始终跨越整行,我建议这样:

import re
s = """1. becomes a h1 tag
A. becomes a h2 tag
(1) becomes a h3 tag
and so on..."""

regexes = {r"\d+\.": "h1",
           r"[A-Z]+\.": "h2",
           r"\(\d+\)": "h3",
          }

for regex in regexes:
    repl = regexes[regex]
    s = re.sub("(?m)^" + regex + ".*", "<" + repl + ">" + r"\g<0>" + "</" + repl + ">", s)

print(s)

结果:

<h1>1. becomes a h1 tag</h1>
<h2>A. becomes a h2 tag</h2>
<h3>(1) becomes a h3 tag</h3>
and so on...

<强>解释

修改每个正则表达式(仅与实际标识符匹配)以匹配从行的开头到行的结尾:

"(?m)^" + regex + ".*" # (?m) allows ^ to match at the start of lines

整个匹配包含在组0中,可以通过\g<0>在替换字符串中访问。

"<" + repl + ">" + r"\g<0>" + "</" + repl + ">"  # add tags around line

答案 1 :(得分:0)

为了将来参考并关闭它,我最终提出的是贯穿整个文本字符串并首先删除一些垃圾。实际上有15个用于此步骤。

$regexes['lf'] = "/[\n\r]*/";
$regexes['tab-cr-lf'] = "/\t[\r\n]/";
preg_replace($regexes,"", $string);

然后我发现在每个标题标识符之后我可以指望空格和\t,所以我在字符串上运行了一些更多的正则表达式

$regexes['step1'] = "/(\d{1,2}\..\t)/";
$regexes['step2'] = "/([A-Z]\. \t)/";
$replacements['step1'] = "\n\n<step1>$0";
$replacements['step2'] = "\n\n<step2>$0";
preg_replace($this->headerRegexes, $replacements, $string);

这些步骤为我提供了一些可以使用的可用文本。

感谢所有插话的人,当我解决这个问题时,它给了我一些思考。