舍得英语魔法学苑

 找回密码
 注册
查看: 368|回复: 6

[UX] 正则表达式处理复杂文本思路[图文]

  [复制链接]
  • TA的每日心情
    擦汗
    昨天 06:03
  • 签到天数: 1663 天

    [LV.Master]伴坛终老

    qixiaobin0715 发表于 2018-9-30 14:03:17 | 显示全部楼层 |阅读模式
    本帖最后由 qixiaobin0715 于 2018-9-30 14:08 编辑


        我第一次接触正则表达式还是从舍得的帖子“正则表达式实用教程”开始的。没有学习正则之前,制作课程想想真是太累了。自从开始认识正则,边学边做挺有成就感的。从简单的,再到复杂的,一路下来制作了不少课程,有给自己用的,有给孩子用的,还有给朋友用的。通过这几年的学习,也积攒了不少心得体会,但一直没有进行总结。
        现在虽然学苑里没以前热闹了,我发现关于正则表达式的帖子还是有不少人关注的,以前这方面的帖子时不时就被翻出来,除了舍得的帖子外,最近又看到“优仕新概念源文本处理之短语篇(正则表达式教程)”(2013年)成为热帖,以前刚接触正则时也曾看过,受益匪浅,当时是以初学者的态度学习的。现在又重新浏览,虽然是时过境迁,还是有新的收获。因为现在自己也有些许心得,所以在浏览过程中主要是思考他的处理文本时的思路,思考如果是换作自己如何做。
        我以前制作课程后,处理的文本都没有保留,手头又没有典型的文本可用,而xsqxsy兄提供的原始文本和处理后的文本比较全,更具代表性,所以就想以xsqxsy兄的源文件为例对应用正则表达式处理文本的思路、方法、技巧进行总结,分享给大家,同时使自己也能得到提高。没有事先征得xsqxsy兄的同意而利用其资料,恳请不要怪罪。
        本想将自己的体会附在以上提到的两个帖子中一个,最终还是决定开个新帖:一则舍得的帖子是引导大家去学习正则的,提炼出拿来就能用的条目,所谓“实用”的由来;其次xsqxsy兄的帖子也花了不少心思,构思严谨实用,但其只是针对特定文本处理的过程做一说明。
        本帖重点在于对源文本处理的思路进行探讨,也即是拿到想要制作课程的资源,如何对其文本部分进行分析,如何处理文本才能达到自己想要的格式。由于是以xsqxsy兄的源文件作为例子,可能叙述过程中,要与帖子中的部分步骤做对比,本人绝无意与人争一高下,而是为了更好地说明自己的思路,敬请谅解。
        开场白有点太长了哈,但是有些情况还是要先说清楚的好,这也是激励自己不要在后面搞的虎头蛇尾,惹人议论。后面的内容可都是干货了,先占个位置。节后一期一期的慢慢道来。
    xsqxsy兄课程链接:
  • TA的每日心情
    难过
    6 天前
  • 签到天数: 403 天

    [LV.9]以坛为家II

    wsqiyijiang 发表于 2018-10-7 10:02:10 | 显示全部楼层
    厉害,正则的运用真的可以省去好多麻烦
  • TA的每日心情
    难过
    6 天前
  • 签到天数: 403 天

    [LV.9]以坛为家II

    wsqiyijiang 发表于 2018-10-7 10:02:30 | 显示全部楼层
    厉害,正则的运用真的可以省去好多麻烦
    [发帖际遇]: 一个袋子砸在了 wsqiyijiang 头上,wsqiyijiang 赚了 2 颗 魔晶石. 幸运榜 / 衰神榜
  • TA的每日心情
    擦汗
    昨天 06:03
  • 签到天数: 1663 天

    [LV.Master]伴坛终老

     楼主| qixiaobin0715 发表于 2018-10-9 12:33:56 | 显示全部楼层
          当你拿到一份资料后如何将其最终制作成满意的课程呢?下面就正式探讨这一问题。
          现在先理一理思路,列一个大概的提纲,省得以后东一榔头西一棒子的。可能以后还会做少许调整:
          一、        如何对全部资料进行分析?包括文本、音频、图片、影像等。
          二、        如何对文本资料进行分析。
          三、        文本处理的大致思路。
          四、        文本处理用到几种不容易理解或容易理解错误的正则表达式的解析。
          五、        用实例说明文本处理的全过程。


          首先对第一点进行说明:
          本文主要是谈对文本处理的体会,但是其他资料也必须建立与文本的联系,才能制作内容丰富的课程,所以对这一部分也要进行简单的说明。
          处理文本前首先要看看手中的其他资料与文本之间是如何关联的:

          1.        文本内容如果与图片音频影像没有直接联系,就要想办法让其发生联系。
          2.        对于相对独立的图片音频影像处理起来较为容易,可直接提取文件名(用cmd中的DIR命令或批处理bat)并按文本顺序排列,然后插入文本。
          3.        如果图片音频影像不是相对独立的话,处理起来就麻烦的多了。比如图片是PDF文件并连在一起,音频影像是一段一段的,就需要用专用软件切割。图片切割推荐用snagit,音频影像建议用Aboboo。
          4.        如果文本内容中有与图片音频影像相联系的内容,处理文本时一定小心应对,千万不能丢失这些联系。

    [发帖际遇]: qixiaobin0715 乐于助人,奖励 9 分 学分. 幸运榜 / 衰神榜
  • TA的每日心情
    擦汗
    昨天 06:03
  • 签到天数: 1663 天

    [LV.Master]伴坛终老

     楼主| qixiaobin0715 发表于 2018-10-11 09:38:45 | 显示全部楼层

    二、对文本资料进行分析
      文本资料是制作课程的核心。文本资料的分析是极其重要的环节,对后面的文本处理、课程模型的构思起到非常关键的作用。分析文本时主要关注以下内容:
      1. 文本资料格式是什么,是多个还是单个?文本资料无论是什么格式,处理前都要转换为txt文件。单个文本文件就不用说了,若是多个文本文件(比如几十上百甚至更多)可采用抽样分析,一般不应低于5%(文件太多时不少于10个)。这样做可减少以偏概全的错误。
      2. 其次要了解文本的基本结构,对每一部分进行分类。比如这部分是第一章的内容,那是第三章;具体到每一章中,哪里是“标题行”,哪里是“对话”,哪里是“练习题”,哪些是对课程无用的标记(索引、页码、页眉页脚等),都要搞清楚。
      3. 对第2点分析完后,还要进一步了解每一部分内部的结构,各部分之间的关系如何,哪些行需要合并,哪些内容需要分隔。
      下面就以xsqxsy兄提供的一个文本文件中的第一课的文本来说明如何分析文本。
      为了便于说明我们作如下规定:
      每一课就叫:                                     章(或课)
      每段相连单词或相连短语或相连对话等分别就叫:     单元
      每个单词或短语等的内容:                         节
      文本部分截图如下。图1、2、3、4是按顺序截取的典型文本样本,可参照“优仕新概念源文本处理之 短语篇”下载文本资料,为了使大家便于对照学习,截图包括了行号(最左边)。应如此这般的分析文本特征:
      1. 红圈标识代表章,蓝方标识为单元,黄圆尖标识为节,箭线指向分界位置,钢笔圈起来的部分为特殊标记。
      2. 图1红圈A到图4红圈A的范围内也即第1~460行是第一课(章)的内容。课的标记为@L+数字。L——lesson。图4红圈B代表新一课的起点。
      3. 图1蓝方a到图2蓝方a(4~145行)为一个单元单词的内容。单元的标记为P000000dc,dc——单词,每个单元有多个标记。
      4. 图2蓝方b到图3蓝方b(146~198行)为一个单元短语的内容。单元的标记为P000000dy,dy——短语。以此类推。
      5. 图1黄圆尖1为单元a中的一节内容,即高亮部分为单词go的内容。
      6. 第1、2、3节中,红色短箭头表示在一行内不同内容的分界线,如第148行第一个箭头是短语音频代码taf0034与英语短语的分界,第二个箭头是短语(或句子)与中文含义的分界(三个空格)。处理文本时这些位置需用制表符分隔。
      7. 黄色箭头英汉分行的分界,注意特征:行首三个空格。处理文本时应合并为一行且用制表符隔开。
      8. 白色箭头为两行英文,本来就应当合并在一行中,特征与上一条相同。处理文本时直接合并为一行,不需要制表符分隔。源文本中未分行,个别地方有此情况出现,为减少截图,我自己修改的。
      9. 红色钢笔圈中的部分也即~S,为音频代码标记,它们后面的字母加数字部分(不包括~S)为音频代码,也即是音频资料中音频的文件名。如第453行音频代码为C2083002,~S中的S为sound的第一个字母。
      10. 叉号表示文本不需要的部分,特征为紧靠“课”或“节”的后面,中间没有空白行相隔,会对处理文本带来麻烦。一种是以“& ~C~P000000choose”开头(可能是程序需选择单词、短语、句型、对话、短文等“单元”;另一种是以“~N”(可能number开头字母)开头,以dn.、up.或bk.结尾,可能是程序中向上、向下、返回指令。这些内容是处理文本时首先要去除的。









      以上就是分析文本的一个思路,处理文本时,每进行一步还是要对每次处理完的文本进行分析,以免出错,影响后续的处理。自己分析文本时,可不做标记,但应做到心中有数。我是为了讲述方便而为之。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    [发帖际遇]: 一个袋子砸在了 qixiaobin0715 头上,qixiaobin0715 赚了 1 颗 魔晶石. 幸运榜 / 衰神榜
  • TA的每日心情
    擦汗
    昨天 06:03
  • 签到天数: 1663 天

    [LV.Master]伴坛终老

     楼主| qixiaobin0715 发表于 2018-10-16 11:11:47 | 显示全部楼层
    三、文本处理的大致思路
       
      前面已经就文本的分析进行了探讨,得到了文本的基本结构。
      处理文本前还要了解UX课程与最终处理的文本有何关系:
      
      1.        最终处理的文本的每一“行”包含了与之对应的UX课程一个“页面”几乎所有的信息,也即是每一行对应一个页面;
      2.        信息可以是显性的,也可能是隐性的。如上节所说的音频代码是显性的,如果你有以单词命名的音频库图片库,单词栏就可以作为隐性信息,既可以作为页面中的文本用,也可作为提取音频或者图片的代码;
      3.        如果想用舍得的转换精灵制作课程的话,最终处理好的文本就必须采取固定格式,文本中不同信息都必须用制表符隔开。
      4.        用上节中的图片来说,UX主窗体(中间部分)的内容与例子中的每一节(高亮部分)一一对应;
      5.        UX课程如果要划分章节的话,也要在每行中体现章节信息,对应页面中的侧栏和顶栏。
       
      详细对应关系可参照xsqxsy兄的另一个帖子http://emagic.org.cn/thread-24581-1-1.html中的内容。里面有非常详尽的说明。
       
      综上所述处理文本的目的就是要把需要部分的每节的内容分别合并为一行,不同的信息用制表符隔开。
      xsqxsy兄处理文本的思路是先删除单词、句型、对话、短文、其他无用信息等内容,保留短语部分,再进行处理。其好处是可排除干扰,集中精力处理“有用”信息。这也是一种思路,其中还用到了“.”匹配换行符的功能。
      这里我提供另一种思路。除了短语内容之外,单词、句型、对话、短文等可以留作以后制作其他课程用,这部分先保留,经过分析,其结构与短语部分有许多相同之处,处理短语的时候这部分也能得到相应的处理,以后用这些材料制作课程时可减少不少文本处理工作量。“.”匹配换行符是正则表达式中的扩展功能,一般默认处于关闭状态,正则表达式通常都是在行内起作用,这是有它的道理的。开启扩展功能,增加了表达式匹配的复杂性,这时一定要头脑清醒,否则会造成误配,理解起来也有难度,不适合初学者;对于超大内容的文本即使匹配无误,也会造成匹配效率低,速度慢的现象。xsqxsy兄有几处替换需进行多次,究其原因是由于使用了跨行匹配,不知道要替换几次,容易造成困惑,建议采用行内匹配。实际上不开启“.”扩展功能也能进行跨行匹配,但也要尽量避免使用,具体跨行匹配和行内匹配的区别下节具体说明。
      处理文本时,可先去掉真正无用且对处理文本有干扰的信息,比如图中打叉部分。随后应把焦点放在短语部分,兼顾其他进行处理。当进行到短语部分的每一节分别合并为一行时,这时应当把文本进行备份,留作制作其他课程用。这时短语部分行首就有了特殊标志,与其他部分就能区分开来,短语部分就能提取出来。将每一课的内容分别合并为一行,以便进一步处理,这就是我所说的尽可能进行行内处理。将每个短语的内容前加上章节号也即是“第**课”并分行。每行行首加词条序号,首行加上列标题。就此文本处理就告一段落。此处只是大致描述文本处理过程,可能不太好理解,看完后面具体图文处理过程就明白了。
       
    [发帖际遇]: 一个袋子砸在了 qixiaobin0715 头上,qixiaobin0715 赚了 5 颗 魔晶石. 幸运榜 / 衰神榜
  • TA的每日心情
    擦汗
    昨天 06:03
  • 签到天数: 1663 天

    [LV.Master]伴坛终老

     楼主| qixiaobin0715 发表于 5 天前 | 显示全部楼层

      四、文本处理用到几种不容易理解或容易理解错误的正则表达式的解析
      
      从这里开始一直到结束的内容,会一直以正则表达式为核心,所以一定要对正则表达式有一定的基础才能看懂。这个帖子主要是讲文本处理的,不是讲解正则表达式的,对正则不是太了解的,应当先去认真学习后再看以下内容。正则表达式的各种表达形式单个讲起来很简单,但是组合起来相当复杂,即使是多年的老手也会出错。我在文本处理过程中使用正则表达式时,力求简单明了,让大家更容易理解。
      
      1. .*和.*?
      
      正则表达式中经常碰到“.?”、“.*”、“.+”和“.??”、“.*?”、“.+?”及其他变种,你知道它们之间有何区别吗?下面先以.*和.*?进行辨析:
      许多人在学习正则表达式时,对上面两种式子没有理解透彻。
      常见正则表达式元字符分为以下几个大类:
      a.字符表示法;b.字符组及相关结构;c.锚点及其他“零长度断言”;d.注释和模式修饰词;e.分组、捕获、条件判断和控制。
      “.”可以归属为b类,它是几乎能匹配任何字符的元字符,其后无量词时,表示匹配单个字符。量词属于e的“控制”类别,主要是对某一字符、字符组或表达式的数量进行限定的。量词分为匹配优先、忽略优先和占有优先量词三类,前两类较为常用。?、*、+是属于匹配优先量词的,也叫贪婪量词,匹配尽可能多的内容;??、*?、+?属于忽略优先量词,也叫懒惰量词,匹配尽可能少的内容,只需要满足下限,匹配就能成功。下面就以具体例子来说明.*和.*?的区别。*表示它前面的元素可以有任意多,也可以没有。
      先说两者之间的相同点,都表示可以匹配任意多的字符或者如果不匹配任何字符也可以。其区别也是非常明显:
      .*所谓表示匹配优先(贪婪),是指当轮到.*匹配时,会从当前位置向后只要能匹配就尽可能多的进行匹配,直到不能匹配为止,才会停下来。若整个表达式没有结束,其后面还有其它元素或子表达式需要匹配且不能匹配成功,它就会把已经匹配字符中从最后一个开始逐个交还给其它元素或子表达式匹配,直到其后面的元素或子表达式匹配成功为止。
      图5给出了其匹配情况(图中显示的是文本中第一行的内容,在菜单“查看”中选中“按窗口换行”,便于观察第一行的整个内容)。正则表达式为^.*###,匹配文本的过程为:^表示锚点,属于c类,不匹配任何字符,只是说明整个正则表达式匹配起点为行首;接着用.*匹配文本,由于是匹配优先,.能匹配任何字符(除换行符外),所以从行首的第一个字符一直匹配到行尾都符合要求;再匹配###,由于前面已经匹配到了行尾,###不能匹配成功,就要首先交还最后一个字符“。”,还是不能匹配成功,再交还下一个字符“鞋”进行匹配,还是不能匹配,继续交还。如此反复直到退回到图中两个红色箭头之间的###为止,整个表达式匹配成功。匹配过程结束,匹配结果就是高亮部分。文本中间的多个###被.*优先匹配,如黑箭头所示,表达式中的###只是匹配了文本中最后一个###。
      

      
      而对于忽略优先的表达式.*?匹配过程与上述过程正相反。当轮到它进行匹配某个字符时就会对后面的“家伙”说,我先歇歇你来上,后面的也匹配不上时它才站出来匹配这个字符。然后继续下一个字符,直到整个表达式匹配完成。
      图6给出了其匹配情况。正则表达式为^.*?###,匹配文本的过程为:从行首第一个红色箭头开始先用.*?匹配@,由于是忽略优先,就让给后面的###先匹配,但没有匹配成功,回过来.*?再匹配@,成功;接着开始匹配第二个字符L,还是让###先匹配,失败后.*?匹配成功;如此反复直到匹配到第二个红色箭头,整个表达式匹配成功,匹配过程结束,匹配结果就是图中高亮部分。
      
      
      如果像图5那样的文本,行首是###时,.*?###匹配又是如何进行呢?首先.*?匹配第一个#,但由于是忽略优先表达式,所以先忽略匹配,由后面的###匹配,结果成功,整个表达式匹配结束。匹配结果就是行首的三个#,因为.*?(.*也是)不匹配任何字符,也算匹配成功。匹配结果如图7所示:
      
      
      总之用一句话来概括就是:匹配优先的正则表达式尽可能多的匹配文本中的字符直到整个表达式匹配完成,而忽略优先的尽可能少的匹配直到整个表达式匹配成功。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    小黑屋|手机版|Archiver|官方微博|官方QQ群|舍得英语魔法学苑 ( 冀ICP备11024081号-1 )

    GMT+8, 2018-10-24 00:43 , Processed in 0.079747 second(s), 24 queries .

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表