背景描述

编程或者文档处理过程, 经常遇到需要将一个单词修改为另外一个单词的情况, 例如 命名为 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. Codeforces Round #233 (Div. 2) A、Pages

    #include <iostream> using namespace std; int main(){ int n,p,k; cin >> n >> p > ...

  2. 使用jQuery 的.on() 提交表单

    示例: $(function () { $(document).on('submit', '#FormId', function () { var val = $("#Name") ...

  3. Bootstrap_让Bootstrap轮播插件carousel支持左右滑动手势的三种方法

    Bootstrap 的 carousel.js 插件并没有支持手势. 3种解决方案 : jQuery Mobile (http://jquerymobile.com/download/) $(&quo ...

  4. 关于多条id相同,只取其中一条记录的sql语句

    需要使用:分区函数用法(partition by 字段) select *,row_number() over(partition by item order by date  ) as index ...

  5. 使用css让XML文件按照HTML的风格显示出来

    attrib.css name { display:block; color:blue; font-size:20pt; font-weight:bold; } id,company,email,te ...

  6. LaTex Font Size 字体大小命令

    LaTex中字体大小有很多中等级,分别由下列命令控制: \tiny \scriptsize \footnotesize \small \normalsize \large \Large \LARGE ...

  7. Python之路(一)

    学了一整子python,目前看到了处理“列表”的地方,目前列表给我的感觉十分像数组,但不是java中的数组,更像是php中的数组. (1)创建列表的方法:列表名 = [列表项0,列表项1,······ ...

  8. 【HDU4630 No Pain No Game】 dp思想+线段树的离线操作

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4630 题意:给你n个数据范围在[1,n]中的数,m个操作,每个操作一个询问[L,R],让你求区间[L, ...

  9. Maven学习 (四) 使用Nexus搭建Maven私服

    为什么要搭建nexus私服,原因很简单,有些公司都不提供外网给项目组人员,因此就不能使用maven访问远程的仓库地址,所以很有必要在局域网里找一台有外网权限的机器,搭建nexus私服,然后开发人员连到 ...

  10. 【转】Eclipse 常用快捷键 (动画讲解)

    Eclipse有强大的编辑功能, 工欲善其事,必先利其器, 掌握Eclipse快捷键,可以大大提高工作效率. 小坦克我花了一整天时间, 精选了一些常用的快捷键操作,并且精心录制了动画, 让你一看就会. ...