.net - metodos - string replace c#
¿Hay un equivalente a ''sscanf()'' en.NET? (8)
.NET Framework nos da el método de Formato :
string s = string.Format("This {0} very {1}.", "is", "funny");
// s is now: "This is very funny."
Me gustaría una función "Unformat", algo así como:
object[] params = string.Unformat("This {0} very {1}.", "This is very funny.");
// params is now: ["is", "funny"]
Sé que existe algo similar en la biblioteca ANSI-C ( printf vs scanf ).
La pregunta: ¿hay algo similar en C #?
Actualización: la captura de grupos con expresiones regulares no es la solución que necesito. También son una forma. Estoy buscando un sistema que pueda funcionar en ambos sentidos en un solo formato. Está bien renunciar a algunas funcionalidades (como tipos e información de formato).
@mquander: en realidad, PHP lo resuelve incluso diferente:
$s = "This is very very funny.";
$fmt = "This %s very %s.";
sscanf($s, $fmt, $one, $two);
echo "<div>one: [$one], two: [$two]</div>/n";
//echo''s: "one: [is], two: [very]"
Pero tal vez su comentario de expresión regular puede ayudarme. Solo necesito reescribir "This {0} very {1}."
a algo así como: new Regex(@"^This (.*) very (.*)/.$")
. Esto debe hacerse de manera programática, así que puedo usar una cadena de formato en la interfaz de clase pública.
Por cierto: ya tengo un analizador para encontrar los parámetros: vea la entrada del blog Named Format Redux de Phil Haack (y sí, también quiero que los parámetros nombrados funcionen en ambos sentidos).
No existe tal método, probablemente debido a problemas para resolver ambigüedades:
string.Unformat("This {0} very {1}.", "This is very very funny.")
// are the parameters equal to "is" and "very funny", or "is very" and "funny"?
Los grupos de captura de expresiones regulares están hechos para este problema; es posible que desee examinarlos.
Podría hacer string [] parts = string.Split (''''), y luego extraer por la posición del índice partes [1] y partes [3] en su ejemplo.
Regex con agrupamiento?
/This (.*?) very (.*?)./
Sí. Estas se llaman "expresiones regulares". El que hará la cosa es
This (?<M0>.+) very (?<M1>.+)/.
Me encontré con el mismo problema, creo que hay una solución elegante que usa REGEX ... pero surgió una función en C # para "UnFormat" que funciona bastante bien. Perdón por la falta de comentarios.
/// <summary>
/// Unformats a string using the original formating string.
///
/// Tested Situations:
/// UnFormat("<nobr alt=/"1/">1<nobr>", "<nobr alt=/"{0}/">{0}<nobr>") : "1"
/// UnFormat("<b>2</b>", "<b>{0}</b>") : "2"
/// UnFormat("3<br/>", "{0}<br/>") : "3"
/// UnFormat("<br/>4", "<br/>{0}") : "4"
/// UnFormat("5", "") : "5"
/// UnFormat("<nobr>6<nobr>", "<nobr>{0}<nobr>") : "6"
/// UnFormat("<nobr>2009-10-02<nobr>", "<nobr>{0:yyyy-MM-dd}<nobr>") : "2009-10-02"
/// UnFormat("<nobr><nobr>", "<nobr>{0}<nobr>") : ""
/// UnFormat("bla", "<nobr>{0}<nobr>") : "bla"
/// </summary>
/// <param name="original"></param>
/// <param name="formatString"></param>
/// <returns>If an "unformat" is not possible the original string is returned.</returns>
private Dictionary<int,string> UnFormat(string original, string formatString)
{
Dictionary<int, string> returnList = new Dictionary<int, string>();
try{
int index = -1;
// Decomposes Format String
List<string> formatDecomposed = new List<string> (formatString.Split(''{''));
for(int i = formatDecomposed.Count - 1; i >= 0; i--)
{
index = formatDecomposed[i].IndexOf(''}'') + 1;
if (index > 0 && (formatDecomposed[i].Length - index) > 0)
{
formatDecomposed.Insert(i + 1, formatDecomposed[i].Substring(index, formatDecomposed[i].Length - index));
formatDecomposed[i] = formatDecomposed[i].Substring(0, index);
}
else
//Finished
break;
}
// Finds and indexes format parameters
index = 0;
for (int i = 0; i < formatDecomposed.Count; i++)
{
if (formatDecomposed[i].IndexOf(''}'') < 0)
{
index += formatDecomposed[i].Length;
}
else
{
// Parameter Index
int parameterIndex;
if (formatDecomposed[i].IndexOf('':'')< 0)
parameterIndex = Convert.ToInt16(formatDecomposed[i].Substring(0, formatDecomposed[i].IndexOf(''}'')));
else
parameterIndex = Convert.ToInt16(formatDecomposed[i].Substring(0, formatDecomposed[i].IndexOf('':'')));
// Parameter Value
if (returnList.ContainsKey(parameterIndex) == false)
{
string parameterValue;
if (formatDecomposed.Count > i + 1)
if (original.Length > index)
parameterValue = original.Substring(index, original.IndexOf(formatDecomposed[i + 1], index) - index);
else
// Original String not valid
break;
else
parameterValue = original.Substring(index, original.Length - index);
returnList.Add(parameterIndex, parameterValue);
index += parameterValue.Length;
}
else
index += returnList[parameterIndex].Length;
}
}
// Fail Safe #1
if (returnList.Count == 0) returnList.Add(0, original);
}
catch
{
// Fail Safe #2
returnList = new Dictionary<int, string>();
returnList.Add(0, original);
}
return returnList;
}
Si alguien está interesado, acabo de publicar un reemplazo de scanf()
para .NET. Si las expresiones regulares no son suficientes para usted, mi código sigue bastante de cerca la cadena de formato scanf()
.
Puede ver y descargar el código que escribí en http://www.blackbeltcoder.com/Articles/strings/a-sscanf-replacement-for-net .
Hago referencia a la respuesta anterior, escribí una muestra, veo lo siguiente
string sampleinput = "FirstWord.22222";
Match match = Regex.Match(sampleinput, @"(/w+)/.(/d+)$", RegexOptions.IgnoreCase);
if(match.Success){
string totalmatchstring = match.Groups[0]; // FirstWord.22222
string firstpart = match.Groups[1]; // FirstWord`
string secondpart = match.Groups[2]; // 22222
}