背景描述

编程或者文档处理过程, 经常遇到需要将一个单词修改为另外一个单词的情况, 例如 命名为 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. IOS关于UIViewController之间的切换

    IOS关于UIViewController之间的切换 1.NavigationController切换UIViewController的两种方式 方法一右侧进入 1 SecondViewControl ...

  2. 【BZOJ3343】教主的魔法 分块+二分

    Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的 ...

  3. 深入浅出 - Android系统移植与平台开发(二) - 准备Android开发环境

    作者:唐老师,华清远见嵌入式学院讲师. 编译Android源码 关于android系统的编译,Android的官方网站上也给出了详细的说明.http://source.android.com/sour ...

  4. 无法将Win7安装到GPT分区下解决办法

    当出现"您想将windows安装 在何处时",按shift+F10打开命令提示符,输入:diskpartlist disksel disk 0cleanconvert mbr完成转 ...

  5. 关于C# WinForm 边框阴影窗体(一)

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...

  6. 关于Autoit上传文件的问题

    Autoit上传文件需要安装两个软件: 使用这个做文件上传时:在代码中需要添加的代码如下: Runtime.getRuntime().exec("d:/zhpg.exe"); D盘 ...

  7. ubuntu 上安装 NASM 汇编开发工具

    一般系统自带NASM可通过 输入 nasm -version 检查,若是没有 可用下述指令安装: sudo apt-get install nasm 安装过程执行完毕后 再次输入 : nasm -ve ...

  8. JAVA生成二维码图片代码

    首先需要导入 QRCode.jar 包 下载地址看这里   http://pan.baidu.com/s/1o6qRFqM import java.awt.Color;import java.awt. ...

  9. HDU1257

    最少拦截系统 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  10. webapp 侧边导航效果

    @media (max-width: 767px) .main-sidebar, .left-side { -webkit-transform: translate(-230px, 0); -ms-t ...