首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否可以使用正则表达式将标题复制到每个条目,直到下一个标题?(电子书中的超链接尾注)

是否可以使用正则表达式将标题复制到每个条目,直到下一个标题?(电子书中的超链接尾注)
EN

Stack Overflow用户
提问于 2011-08-04 06:11:15
回答 2查看 287关注 0票数 0

好了,雷克斯忍者。我正在尝试设计一种模式,在ePub电子书XHTML文件中添加到尾注的超链接。问题是在每个章节中重新开始编号,所以我需要向锚名称添加一个唯一的标识符,以便散列到它的链接。

给出一个(简单得多)如下的列表:

代码语言:javascript
运行
复制
<h2>Introduction</h2>
<p> 1 Endnote entry number one.</p>
<p> 2 Endnote entry number two.</p>
<p> 3 Endnote entry number three.</p>
<p> 4 Endnote entry number four.</p>

<h2>Chapter 1: The Beginning</h2>
<p> 1 Endnote entry number one.</p>
<p> 2 Endnote entry number two.</p>
<p> 3 Endnote entry number three.</p>
<p> 4 Endnote entry number four.</p>

我需要把它变成这样:

代码语言:javascript
运行
复制
<h2>Introduction</h2>
<a name="endnote-introduction-1"></a><p> 1 Endnote entry number one.</p>
<a name="endnote-introduction-2"></a><p> 2 Endnote entry number two.</p>
<a name="endnote-introduction-3"></a><p> 3 Endnote entry number three.</p>
<a name="endnote-introduction-4"></a><p> 4 Endnote entry number four.</p>

<h2>Chapter 1: The Beginning</h2>
<a name="endnote-chapter-1-the-beginning-1"></a><p> 1 Endnote entry number one.</p>
<a name="endnote-chapter-1-the-beginning-2"></a><p> 2 Endnote entry number two.</p>
<a name="endnote-chapter-1-the-beginning-3"></a><p> 3 Endnote entry number three.</p>
<a name="endnote-chapter-1-the-beginning-4"></a><p> 4 Endnote entry number four.</p>

显然,需要在书的实际文本中进行类似的搜索,其中每个尾注都将链接到endnotes.xhtml#endnote-introduction-1等。

最大的障碍是每次匹配搜索都是在前一次搜索结束之后开始的,所以除非使用递归,否则不能为多个条目匹配相同的位(在本例中是标题)。然而,到目前为止,我对递归的尝试只产生了无限的循环。

我使用的是TextWrangler的grep引擎,但是如果您在不同的编辑器(比如vim)中有一个解决方案,也没问题。

谢谢!

EN

回答 2

Stack Overflow用户

发布于 2011-08-04 06:35:51

一点awk可能会做到这一点:

创建以下脚本(我已将其命名为add_endnote_tags.awk):

代码语言:javascript
运行
复制
/^<h2>/ {
    i = 0;
    chapter_name = $0;
    gsub(/<[^>]+>/, "", chapter_name);
    chapter_name = tolower(chapter_name);
    gsub(/[^a-z]+/, "-", chapter_name);
    print;
}

/^<p>/ {
    i = i + 1;
    printf("<a name=\"endnote-%s-%d\"></a>%s\n", chapter_name, i, $0);
}

$0 !~ /^<h2>/ && $0 !~ /^<p>/ {
    print;
}

然后使用它解析您的文件:

代码语言:javascript
运行
复制
awk -f add_endnote_tags.awk < source_file.xml > dest_file.xml

希望这能有所帮助。如果您使用的是Windows平台,则可能需要通过安装cygwin和awk软件包或下载gawk for Windows来安装awk

票数 1
EN

Stack Overflow用户

发布于 2011-08-04 07:48:37

我认为这很难在文本编辑器中完成,因为它需要两个步骤的过程。首先你需要将文件分成章节,然后你需要处理每一章的内容。假设"endnote paragraphs“(这是您希望添加锚点的位置)被定义为第一个单词等于一个整数单词的段落,则此PHP脚本将执行您所需的操作。

代码语言:javascript
运行
复制
<?php
$data = file_get_contents('testdata.txt');
$output = processBook($data);
file_put_contents('testdata_out.txt', $output);
echo $output;

// Main function to process book adding endnote anchors.
function processBook($text) {
    $re_chap = '%
        # Regex 1: Get Chapter.
        <h2>([^<>]+)</h2>  # $1: Chapter title.
        (                  # $2: Chapter contents.
          .+?              # Contents are everything up to
          (?=<h2>|$)       # next chapter or end of file.
        )                  # End $2: Chapter contents.
        %six';
    // Match and process each chapter using callback function.
    $text = preg_replace_callback($re_chap, '_cb_chap', $text);
    return $text;
}
// Callback function to process each chapter.
function _cb_chap($matches) {
    // Build ID from H2 title contents.
    // Trim leading and trailing ws from title.
    $baseid = trim($matches[1]);
    // Strip all non-space, non-alphanums.
    $baseid = preg_replace('/[^ A-Za-z0-9]/', '', $matches[1]);
    // Append prefix and convert whitespans to single - dash.
    $baseid = 'endnote-'. preg_replace('/ +/', '-', $baseid);
    // Convert to lowercase.
    $baseid = strtolower($baseid);
    $text = preg_replace(
                '/(<p>\s*)(\d+)\b/',
                '<a name="'. $baseid .'-$2"></a>$1$2',
                $matches[2]);
    return '<h2>'. $matches[1] .'</h2>'. $text;

}
?>

这个脚本正确地处理了示例数据。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6933925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档