2012-04-19 23 views
5

Tengo un script de reemplazo de búsqueda que funciona para reemplazar cadenas. Ya tiene opciones para hacer búsquedas insensibles a mayúsculas y minúsculas y coincidencias "escapadas" (por ejemplo, permite buscar% (etc. en la búsqueda)Utilice string.gsub para reemplazar cadenas, pero solo palabras completas

Como siempre se me ha pedido que coincida con palabras completas, he intentado agregar% s a cada extremo, pero eso no coincide con las palabras al final de una cadena y no puedo averiguar cómo atrapar los elementos del espacio en blanco que se encuentran para dejarlos intactos durante el reemplazo.

¿Debo volver a hacer? la secuencia de comandos utilizando string.find y agregar lógica para la comprobación de palabras o esto es posible con patrones.

Las dos funciones que uso para los elementos insensibles a mayúsculas y minúsculas son las siguientes devuelven el patrón para buscar.

-- Build Pattern from String for case insensitive search 
function nocase (s) 
     s = string.gsub(s, "%a", function (c) 
      return string.format("[%s%s]", string.lower(c), 
              string.upper(c)) 
      end) 
     return s 
    end 
function strPlainText(strText) 
    -- Prefix every non-alphanumeric character (%W) with a % escape character, where %% is the % escape, and %1 is original character 
    return strText:gsub("(%W)","%%%1") 
end 

Tengo una manera de hacer lo que quiero ahora, pero es poco elegante. ¿Hay una mejor manera?

local strToString = '' 
    local strSearchFor = strSearchi 
    local strReplaceWith = strReplace 
    bSkip = false 
    if fhGetDataClass(ptr) == 'longtext' then 
     strBoxType = 'm' 
    end 
    if pWhole == 1 then 
    strSearchFor = '(%s+)('..strSearchi..')(%s+)' 
    strReplaceWith = '%1'..strReplace..'%3' 
    end 
    local strToString = string.gsub(strFromString,strSearchFor,strReplaceWith) 
    if pWhole == 1 then 
    -- Special Case search for last word and first word 
     local strSearchFor3 = '(%s+)('..strSearchi..')$' 
     local strReplaceWith3 = '%1'..strReplace 
     strToString = string.gsub(strToString,strSearchFor3,strReplaceWith3) 
     local strSearchFor3 = '^('..strSearchi..')(%s+)' 
     local strReplaceWith3 = strReplace..'%2' 
     strToString = string.gsub(strToString,strSearchFor3,strReplaceWith3) 
    end 

Respuesta

3

tengo una manera de hacer lo que quiero ahora, pero es poco elegante. ¿Hay una mejor manera?

Hay una característica no documentada de la biblioteca de coincidencia de patrones de Lua llama el Frontier Pattern, que le permitirá escribir algo como esto:

function replacetext(source, find, replace, wholeword) 
    if wholeword then 
    find = '%f[%a]'..find..'%f[%A]' 
    end 
    return (source:gsub(find,replace)) 
end 

local source = 'test testing this test of testicular footest testimation test' 
local find = 'test' 
local replace = 'XXX' 
print(replacetext(source, find, replace, false)) --> XXX XXXing this XXX of XXXicular fooXXX XXXimation XXX  
print(replacetext(source, find, replace, true)) --> XXX testing this XXX of testicular footest testimation XXX 
1

Qué quiere decir si pasa nocase foo(), que desea [foofoo] en lugar de [FF] [oO] [oO]? si es así, ¿podrías probar esto?

function nocase (s) 
     s = string.gsub(s, "(%a+)", function (c) 
      return string.format("[%s%s]", string.lower(c), 
              string.upper(c)) 
      end) 
     return s 
end 

y si quieres una manera fácil de dividir una frase en palabras, puede utilizar esto:

function split(strText) 
    local words = {} 
    string.gsub(strText, "(%a+)", function(w) 
            table.insert(words, w) 
            end) 
    return words 
end 

una vez que haya recibido las palabras de división, que es bastante fácil para repetir las palabras en la tabla y hacer una comparación completa contra cada palabra.

+0

No se lo que tengo que hacer es utilizar la cadena de búsqueda procesados ​​que tengo ahora o una variación y hacer que solo coincida con palabras completas, entonces busco "calle" y solo coincidirá con "calle" y no con "broadstreet" –

+0

cómo está usando los valores que obtiene de nocase() y strPlainText() ? eso es mucho más relevante ... –

Cuestiones relacionadas