背景描述

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

    对于双屏异显(lcd 和 hdmi 的双屏异显),android框架已经支持,但是底层接口功能还是要自己去实现,且需要底层驱动支持. 使用presentation 去画第二个display就好了. M ...

  2. ACM 兰州烧饼

    兰州烧饼 时间限制:1000 ms  |  内存限制:65535 KB 难度:1   描述 烧饼有两面,要做好一个兰州烧饼,要两面都弄热.当然,一次只能弄一个的话,效率就太低了.有这么一个大平底锅,一 ...

  3. 【BZOJ】1100: [POI2007]对称轴osi

    题意 给一个\(n(1 \le n \le 100000)\)个点不自交的多边形,求对称轴数目. 分析 将多边形表示成长度和角的形式(用有向面积来表示角也行),然后匹配. 题解 匹配可以用kmp或ma ...

  4. Java_CookieUtil

    package com.willow.util; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequ ...

  5. selenium grid解决多台电脑进行并发执行测试脚本

    1 两台计算机,一台计算机既做HUB,又做Node 机器A设置HUB的步骤: 1 运行---输入cmd 2 输入: cd c:/ 3  输入: java -jar selenium-server-st ...

  6. 可能碰到的iOS笔试面试题(4)--C语言

    可能碰到的iOS笔试面试题(4)--C语言 可能碰到的iOS笔试面试题(4)--C语言 C语言,开发的基础功底,iOS很多高级应用都要和C语言打交道,所以,C语言在iOS开发中的重要性,你懂的.里面的 ...

  7. CSS的class、id、css文件名的常用命名规则

    CSS的class.id.css文件名的常用命名规则        (一)常用的CSS命名规则 头:header       内容:content/container       尾:footer   ...

  8. arrays.xml文件中添加drawable数组的问题

    一.问题描述 今天遇到一个需求,将java中的数组搬进arrays.xml文件中 R.drawable.menu_share_pic_item, R.drawable.menu_share_wecha ...

  9. R中创建not-yet-evaluated对象

    create not-yet-evaluated object在R中创建 not-yet-evaluated(就是some code we will evaluated later!!)对象;然后执行 ...

  10. 【Hihocoder】1014 : Trie树

    问题:http://hihocoder.com/problemset/problem/1014 给定一个字符串字典dict,输入字符串str, 要求从dict中找出所有以str为前缀的字符串个数. 构 ...