背景描述

编程或者文档处理过程, 经常遇到需要将一个单词修改为另外一个单词的情况, 例如 命名为 shall 修改 为 should。

使用工具实现, 则比较方便,不容易出错, 解放双手。

需求规格

对于某个文件夹中的所有文本文件(txt), 将某个单词替换为目标单词。

实现思路

对于替换的单词映射, 在配置文件config.lua进行设置, 存储一个表,表中每一行 对应  src vocanbulary 和 dest vocanbulary

对应工具的主题逻辑代码在 replace.lua中实现,

待替换的文本文件存储在 replaceFiles文件夹下。

总体目录结果如下:

│  config.lua
│  replace.lua
│ 
└─replaceFiles
        test.txt

代码说明

代码实现路径:

https://github.com/fanqingsong/code-snippet/tree/master/lua/replace

config.lua

-- ttanslating table, in every line first word is source, second word is destination
trans_table_string = [[
    you  lucy
]]

待替换文件 test.txt

I love you

replace.lua工具逻辑代码实现

--[[
/*******************************************************************************
*  Author:
*  Date:
*  Description: set config for replace, replace by config in files of target path
*  Changes:
*******************************************************************************/
]]

local require = require
local io = io
local ipairs = ipairs
local assert = assert
local print = print
local string = string
local lfs = require"lfs"

local transFilePath = "./replaceFiles"

string.split = function(str, pat, max, regex)
    pat = pat or "\n"
    max = max or #str

local t = {}
    local c = 1

if #str == 0 then
        return {""}
    end

if #pat == 0 then
        return nil
    end

if max == 0 then
        return str
    end

repeat
        local s, e = str:find(pat, c, not regex)
        max = max - 1
        if s and max < 0 then
            t[#t+1] = str:sub(c)
        else
            t[#t+1] = str:sub(c, s and s - 1)
        end
        c = e and e + 1 or #str + 1
    until not s or max < 0

return t
end

------------------------------------------  parse start ------------------------------------------
local trans_vocabulary_table = {
    --["sourcevocabulary"] = "destvocabulary"
}

local function construct_vocabulary_table()
    require("config")
   
    print("parse trans_table starting .....")
   
    -- 禄帽募镁?拢卢 禄禄?路没  \n 潞?\r\n
    local lineSep = "\r\n"
    if string.find(trans_table_string, "\r\n") then
        lineSep = "\r\n"
    elseif string.find(trans_table_string, "\n") then
        lineSep = "\n"
    elseif string.find(trans_table_string, "\r") then
        lineSep = "\r"
    end

local lines = trans_table_string:split(lineSep)

for _,line in ipairs(lines) do
        print("line="..line)

local src, dest = string.match(line, "([%w_]+)%s+([%w_]+)")

if src then
            print("well formed line="..line)
           
            trans_vocabulary_table[src] = dest
        end
    end
 
      print("parse trans_table ending .....")
   
end

-- parse table
construct_vocabulary_table()

------------------------------------------  parse end ------------------------------------------

------------------------------------------  read file list start ------------------------------------------
local targetFiles = {}

local function infilter(file, filters)
    if filters == nil or filters == "*" then
        return true
    end

for _, v in pairs(filters) do
        if string.find(file, "%."..v.."$") then
            return true
        end
    end
   
    return false
end

local function splitonlast (path, sep)
    local dir, file = string.match(path,"^(.-)([^:/\\]*)$")
    return dir, file
end

function readdir(dir, filelist, filters)
    for file in lfs.dir(dir) do
        if file ~= ".." and file ~= "." then
            local f = dir.."/"..file
            if lfs.attributes(f).mode == "directory" then
                readdir(f, filelist, filters)
            else
                if infilter(file, filters) then
                    table.insert(filelist, f)
                end
            end
        end
    end
end

readdir(transFilePath, targetFiles, {"*"})

for _,file in ipairs(targetFiles) do
    --print("c file =".. file)
end

------------------------------------------  read file list end ------------------------------------------

------------------------------------------  handle file start ------------------------------------------

local function handle_file(file)
    local lineBuff = {}

-- ?赂?搂?
    local fh = assert(io.open (file, "rb"))
    local contents = fh:read("*a")
    fh:close()
    --print(contents)
    for src,dest in pairs(trans_vocabulary_table) do
        print(src.."==>"..dest)
        contents = string.gsub(contents, src, dest)
    end

--[[
    -- 禄帽募镁?拢卢 禄禄?路没  \n 潞?\r\n
    local lineSep = "\r\n"
    if string.find(contents, "\r\n") then
        lineSep = "\r\n"
    elseif string.find(contents, "\n") then
        lineSep = "\n"
    elseif string.find(contents, "\r") then
        lineSep = "\r"
    end

local fileLines = string.split(contents, lineSep)

for _,line in ipairs(fileLines) do
        --print(" handle_file line= "..line)
           
        local gotPattern = false
        for src,dest in pairs(trans_vocabulary_table) do
            --print("src="..src.."----")
            local s, e = string.find(line, "%s-%(%s-"..src.."%s-,%s-%\"")
            if s then
                print("!!!! ------- gotPattern ------- src ="..src)

gotPattern = true

-- the part before OssUsersrc
                local head = string.sub(line, 1, s-1)
                -- tail part = now");
                --print(head)
                local tail = string.sub(line, e+1)
                --print("tail="..tail)
                --print("tail[1]="..string.sub(tail, 1,1))

-- OssUserLogType(LOG_LEVEL_NOTICE, LOG_TYPE_SYSTEM, "the system will reboot now");
                local level = dest["level"]
                local types = dest["types"]
                local msg = dest["msg"]

local sep = " "
                if msg == "" then
                    sep = ""               
                elseif string.sub(tail, 1,1) == "\"" then
                    sep = ""
                end
                --print("msg="..msg.."sep="..sep.."--")
                local transLine = head .. "OssUserLogType(" .. level ..", " .. types .. ", \"" .. msg .. sep .. tail

table.insert(lineBuff, transLine)

if gotPattern then
                    break
                end

end
        end

if not gotPattern then
            table.insert(lineBuff, line)
        end
    end
   
]]
    --write buff to orig file
    local fh = assert(io.open(file, "wb"))
    fh:write(contents)
    fh:close()
end

for _,file in ipairs(targetFiles) do
    print("handling file =".. file)
    handle_file(file)
end

------------------------------------------  handle file end ------------------------------------------

运行结果

root@fqs:/home/share/luascript/replace# cat ./replaceFiles/test.txt

I love you

root@fqs:/home/share/luascript/replace# lua replace.lua
parse trans_table starting .....
line=    you  lucy
well formed line=    you  lucy
line=
parse trans_table ending .....
handling file =./replaceFiles/test.txt
you==>lucy
root@fqs:/home/share/luascript/replace#
root@fqs:/home/share/luascript/replace#
root@fqs:/home/share/luascript/replace# cat ./replaceFiles/test.txt

I love lucy

root@fqs:/home/share/luascript/replace#

LUA实现单词替换功能的更多相关文章

  1. Python3.5 day3作业一:实现简单的shell sed替换功能

    需求: 1.使python具有shell中sed替换功能. #!/usr/bin/env python #_*_conding:utf-8_*_ #sys模块用于传递参数,os模块用于与系统交互. i ...

  2. [word]用Word2007查找和替换功能批量设置图片位置

    Word2007的"查找和替换"功能并不仅仅可以对文字进行批量的查找替换,还有很多神奇的功能,比如对插入的图片位置进行批量的查找和调整等等. 今天我们就来试试Word2007的&q ...

  3. 【九度OJ】题目1111:单词替换

    题目1111:单词替换 题目描述: 输入一个字符串,以回车结束(字符串长度<=100).该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区分大小写.现需要将其中的某个单词替换成另一个单 ...

  4. Visual Studio 2010 实用功能:使用web.config发布文件替换功能

    当建立ASP.NET Web应用程序项目后,默认除了生成web.config外,还生成了web.debug.config与Web.Release.config.顾名思义,根据它们的命名我可以推测到他们 ...

  5. AC日记——单词替换 1.7 21

    21:单词替换 总时间限制:  1000ms 内存限制:  65536kB 描述 输入一个字符串,以回车结束(字符串长度<=100).该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区 ...

  6. OpenJudge计算概论-单词替换

    /*====================================================================== 单词替换 总时间限制: 1000ms 内存限制: 65 ...

  7. UltraEdit (Ctrl + F) 查找、(Ctrl + R)替换功能失效

    环境: Windows 7 Service Pack 1 X64 工具: UltraEdit Version 21 症状: UltraEdit (Ctrl + F) 查找.(Ctrl + R)替换功能 ...

  8. Java基础知识强化76:正则表达式之替换功能

    1. 替换功能: String类的replaceAll方法,如下: public String replaceAll(String regex, String replacement): 使用给定的r ...

  9. Java基础知识强化40:StringBuffer类之StringBuffer的替换功能

    1. StringBuffer的替换功能: public  StringBuffer   replace(int  start,  int  end, String  str): 2. 案例演示: p ...

随机推荐

  1. 【BZOJ】2212: [Poi2011]Tree Rotations

    题意 给一棵\(n(1 \le n \le 200000)\)个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少. 分析 可以发现如果交换非叶结点的左右子树,对子树内的交换无影响, ...

  2. linux系统下yum源的搭建

    1.建立挂载点 系统默认在 /mnt目录 1>创建挂载点 mkdir -p /mnt/cdrom   参数-p是需要时创建目标目录的上层目录,但即使这些目录已存在也不当作错误处理 2>查看 ...

  3. IOS 登陆判断问题

    有一个登陆界面,还有一个包含多个选项卡的界面在ViewController.m中登陆按钮的代码如下 UIViewController *controller=[[Tabbarcontroller al ...

  4. 七、考反映小游戏《苹果iOS实例编程入门教程》

    该app为应用的功能为一个简单的考反应游戏 纲要:-UIButton, UILabel, UIImageView 的运用:-利用rendom增加游戏可玩性: 游戏说明: 在按下开始游戏后,分为三盏的指 ...

  5. 必备:常用px,pt,em换算表(转)

    常用px,pt,em换算表 pt (point,磅):是一个物理长度单位,指的是72分之一英寸. px (pixel,像素):是一个虚拟长度单位,是计算机系统的数字化图像长度单位,如果px要换算成物理 ...

  6. PHP的学习--cookie和session--来自copy_02

    PHP的学习--cookie和session   最近读了一点<PHP核心技术与最佳实践>,看了cookie和session,有所收获,结合之前的认识参考了几篇博客,总结一下-- 1. P ...

  7. 当target属性在XHTML script中无效时

    <a href="#" target=_blank></a>target此属性能够使链接在新窗口打开,但是在XHTML script中无效时. 那么解决方案 ...

  8. [CareerCup] 16.3 Dining Philosophers 哲学家聚餐问题

    16.3 In the famous dining philosophers problem, a bunch of philosophers are sitting around a circula ...

  9. HTML元素事件说明

    blur( ) 元素失去焦点 a, input, textarea, button, select, label, map, area change( ) 用户改变域的内容 input, textar ...

  10. zk回车事件

    private Textbox testTextB; testTextB.addEventListener(Events.ON_OK, new EventListener<Event>() ...