--[[Este módulo está destinado a proporcionar acceso a las funciones de cadena (string) básicas.]]localstr={}--[[lenParametros s: La cadena a encontrar su longitud]]functionstr.len(frame)localnew_args=str._getParameters(frame.args,{'s'});locals=new_args['s']or'';returnmw.ustring.len(s)end--[[subParametros s: La cadena donde extraer la subcadena i: La cadena donde extraer la subcadena. j: Índice final de la subcadena, por defecto la longitud total, hasta el último carácter.]]functionstr.sub(frame)localnew_args=str._getParameters(frame.args,{'s','i','j'});locals=new_args['s']or'';locali=tonumber(new_args['i'])or1;localj=tonumber(new_args['j'])or-1;locallen=mw.ustring.len(s);-- Convertir negativos para la comprobación de rangoifi<0theni=len+i+1;endifj<0thenj=len+j+1;endifi>lenorj>lenori<1orj<1thenreturnstr._error('Índice fuera del rango de la cadena');endifj<ithenreturnstr._error('Índices de la cadena no ordenados');endreturnmw.ustring.sub(s,i,j)end--[[matchParametros s: cadena donde se hace la búsqueda pattern: patrón o cadena a buscar. start: índice de la cadena dónde empezar a buscar, por defecto 1, el primer carácter. match: si se encuentran múltiples coincidencias, especifica cuál de ellas devolver. Por defecto es 1, l la primera coincidencia encontrada. Un número negativo cuenta desde el final, por lo tanto match = -1 es la última coincidencia. plain: indica si el patrón debe interpretarse como texto limpio, por defecto 'false'. nomatch: en caso de no encontrar ninguna coincidencia, devuelve el valor de "nomatch" en lugar de un error. Si el número match o el índice start están fuera del rango de la cadena, entonces la función genera un error. También genera un error si no encuentra ninguna coincidencia. Con el parámetro global ignore_errors = true se suprime el error y devuelve una cadena vacía.]]functionstr.match(frame)localnew_args=str._getParameters(frame.args,{'s','pattern','start','match','plain','nomatch'});locals=new_args['s']or'';localstart=tonumber(new_args['start'])or1;localplain_flag=str._getBoolean(new_args['plain']orfalse);localpattern=new_args['pattern']or'';localmatch_index=math.floor(tonumber(new_args['match'])or1);localnomatch=new_args['nomatch'];ifs==''thenreturnstr._error('La cadena donde buscar está vacía');endifpattern==''thenreturnstr._error('La cadena de búsqueda está vacía ');endifmath.abs(start)<1ormath.abs(start)>mw.ustring.len(s)thenreturnstr._error('Índice d\'inicio fuera del rango de la cadena ');endifmatch_index==0thenreturnstr._error('Número de coincidencias fuera de rango');endifplain_flagthenpattern=str._escapePattern(pattern);endlocalresultifmatch_index==1then-- Encontrar la primera coincidencia es un caso sencillo.result=mw.ustring.match(s,pattern,start)elseifstart>1thens=mw.ustring.sub(s,start);endlocaliterator=mw.ustring.gmatch(s,pattern);ifmatch_index>0then-- Búsqueda hacia adelanteforwiniteratordomatch_index=match_index-1;ifmatch_index==0thenresult=w;break;endendelse-- Invierte búsquedalocalresult_table={};localcount=1;forwiniteratordoresult_table[count]=w;count=count+1;endresult=result_table[count+match_index];endendifresult==nilthenifnomatch==nilthenreturnstr._error('Ninguna coincidencia encontrada');elsereturnnomatch;endelsereturnresult;endend--[[posParámetros target: Cadena donde buscar. pos: Índice del carácter a devolver.]]functionstr.pos(frame)localnew_args=str._getParameters(frame.args,{'target','pos'});localtarget_str=new_args['target']or'';localpos=tonumber(new_args['pos'])or0;ifpos==0ormath.abs(pos)>mw.ustring.len(target_str)thenreturnstr._error('Índice fuera del rango de la cadena');endreturnmw.ustring.sub(target_str,pos,pos);end--[[findParametros source: Cadena donde buscar. target: Cadena a buscar o patrón de búsqueda. start: Índice de la cadena fuente donde empezar a buscar, por defecto 1, el primer carácter. plain: Indica si la búsqueda debe interpretarse como texto limpio, de lo contrario como patrón Lua. Por defecto es 'true'.]]functionstr.find(frame)localnew_args=str._getParameters(frame.args,{'source','target','start','plain'});localsource_str=new_args['source']or'';localpattern=new_args['target']or'';localstart_pos=tonumber(new_args['start'])or1;localplain=new_args['plain']ortrue;ifsource_str==''orpattern==''thenreturn0;endplain=str._getBoolean(plain);localstart=mw.ustring.find(source_str,pattern,start_pos,plain)ifstart==nilthenstart=0endreturnstartend--[[replaceParámetros source: Cadena donde buscar pattern: Cadena de búsqueda o patrón a buscar replace: Texto de reemplazo count: Número de ocurrencias a reemplazar, por defecto todas. plain: Indica si la búsqueda debe interpretarse como texto limpio, de lo contrario como patrón Lua. Por defecto es 'true']]functionstr.replace(frame)localnew_args=str._getParameters(frame.args,{'source','pattern','replace','count','plain'});localsource_str=new_args['source']or'';localpattern=new_args['pattern']or'';localreplace=new_args['replace']or'';localcount=tonumber(new_args['count']);localplain=new_args['plain']ortrue;ifsource_str==''orpattern==''thenreturnsource_str;endplain=str._getBoolean(plain);ifplainthenpattern=str._escapePattern(pattern);replace=mw.ustring.gsub(replace,"%%","%%%%");--Sólo es necesario secuencias de escape.endlocalresult;ifcount~=nilthenresult=mw.ustring.gsub(source_str,pattern,replace,count);elseresult=mw.ustring.gsub(source_str,pattern,replace);endreturnresult;endfunctionstr.mayuscula(frame)-- Convierte en mayúsculas la primera letra que aparece en la edición de una cadenalocals=frame.args[1]or'';ifs~=''thenlocalcambio={};localmodo={};ifstring.find(s,'|')~=nilthen-- Enlaces con etiquetamodo=string.upper(string.match(s,'(|%a)'));cambio=string.gsub(s,'|%a',modo,1);elseifstring.find(s,'[[]')~=nilthen-- Enlaces sin etiquetamodo=string.upper(string.match(s,'^(..%a)'));cambio=string.gsub(s,'^..%a',modo,1);elseifstring.match(s,'^%a')~=nilthen-- Sin enlacemodo=string.upper(string.match(s,'^(%a)'));cambio=string.gsub(s,'^%a',modo,1);elsecambio=s;endreturncambio;endend--[[Función de ayuda que rellena la lista de argumentos, para que el usuario pueda utilizar una combinación de parámetros con nombre y sin nombre. Esto es importante porque los parámetros con nombre no funcionan igual que los parámetros sin nombre cuando se encadenan recortes, y cuando se trata de cadenas a veces se debe conservar o quitar espacios en blanco dependiendo de la aplicación.]]functionstr._getParameters(frame_args,arg_list)localnew_args={};localindex=1;localvalue;fori,arginipairs(arg_list)dovalue=frame_args[arg]ifvalue==nilthenvalue=frame_args[index];index=index+1;endnew_args[arg]=value;endreturnnew_args;end--[[Función de ayuda para controlar los mensajes de error.]]functionstr._error(error_str)localframe=mw.getCurrentFrame();localerror_category=frame.args.error_categoryor'Errores detectados por el módulo String';localignore_errors=frame.args.ignore_errorsorfalse;localno_category=frame.args.no_categoryorfalse;ifstr._getBoolean(ignore_errors)thenreturn'';endlocalerror_str='<strong class="error">Error del módulo String: '..error_str..'</strong>';iferror_category~=''andnotstr._getBoolean(no_category)thenerror_str='[[Categoría:Wikipedia:'..error_category..']]'..error_str;endreturnerror_str;end--[[Función de ayuda para interpretar cadenas booleanas.]]functionstr._getBoolean(boolean_str)localboolean_value;iftype(boolean_str)=='string'thenboolean_str=boolean_str:lower();ifboolean_str=='false'orboolean_str=='no'orboolean_str=='0'orboolean_str==''thenboolean_value=false;elseboolean_value=true;endelseiftype(boolean_str)=='boolean'thenboolean_value=boolean_str;elseerror('Ningún valor booleano encontrado');endreturnboolean_valueend--[[Función de ayuda que escapa a todos los caracteres de patrón para que puedan ser tratadoscomo texto sin formato.]]functionstr._escapePattern(pattern_str)returnmw.ustring.gsub(pattern_str,"([%(%)%.%%%+%-%*%?%[%^%$%]])","%%%1");endreturnstr