c# - regular - sc regex




Regex. Caso de camello para subrayar. Ignorar la primera aparición (5)

Al elaborar la solución de sa_ddam213, la mía extiende esto:

public static string GetConstStyleName(this string value)
        {
            return string.Concat(value.Select((x, i) =>
            {
                //want to avoid putting underscores between pairs of upper-cases or pairs of numbers, or adding redundant underscores if they already exist.
                bool isPrevCharLower = (i == 0) ? false : char.IsLower(value[i - 1]);
                bool isPrevCharNumber = (i == 0) ? false : char.IsNumber(value[i - 1]);
                return (isPrevCharLower && (char.IsUpper(x) || char.IsNumber(x))) //lower-case followed by upper-case or number needs underscore
                    || (isPrevCharNumber && (char.IsUpper(x))) //number followed by upper-case needs underscore
                    ? "_" + x.ToString() : x.ToString();
            })).ToUpperInvariant();
        }

Por ejemplo:

thisIsMySample 

debiera ser:

this_Is_My_Sample

Mi código:

System.Text.RegularExpressions.Regex.Replace(input, "([A-Z])", "_$0", System.Text.RegularExpressions.RegexOptions.Compiled);

Funciona bien, pero si la entrada se cambia a:

ThisIsMySample

La salida será:

_This_Is_My_Sample

¿Cómo se puede ignorar la primera aparición?


Debe modificar su expresión regular para que no coincida con el primer carácter definiendo que desea ignorar el primer carácter por completo

.([A-Z])

La expresión regular anterior simplemente excluye todos los caracteres que vienen primero y, dado que no están entre llaves, estaría en el grupo correspondiente.

Ahora necesitas emparejar el segundo grupo como Bibhu señaló:

System.Text.RegularExpressions.Regex.Replace(s, "(.)([A-Z])", "$1_$2", System.Text.RegularExpressions.RegexOptions.Compiled);

Solución no Regex

string result = string.Concat(input.Select((x,i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())); 

También parece ser bastante rápido: Regex: 2569ms, C #: 1489ms

Stopwatch stp = new Stopwatch();
stp.Start();
for (int i = 0; i < 1000000; i++)
{
    string input = "ThisIsMySample";
    string result = System.Text.RegularExpressions.Regex.Replace(input, "(?<=.)([A-Z])", "_$0",
            System.Text.RegularExpressions.RegexOptions.Compiled);
}
stp.Stop();
MessageBox.Show(stp.ElapsedMilliseconds.ToString());
// Result 2569ms

Stopwatch stp2 = new Stopwatch();
stp2.Start();
for (int i = 0; i < 1000000; i++)
{
    string input = "ThisIsMySample";
    string result = string.Concat(input.Select((x, j) => j > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString()));
}
stp2.Stop();
MessageBox.Show(stp2.ElapsedMilliseconds.ToString());
// Result: 1489ms

Tal vez como

var str = Regex.Replace(input, "([A-Z])", "_$0", RegexOptions.Compiled);
if(str.StartsWith("_"))
   str = str.SubString(1);

// (Preceded by a lowercase character or digit) (a capital) => The character prefixed with an underscore
var result = Regex.Replace(input, "(?<=[a-z0-9])[A-Z]", m => "_" + m.Value);
result = result.ToLowerInvariant();
  • Esto funciona tanto para PascalCase como para camelCase .
  • No crea guiones bajos o finales.
  • Deja intactas cualquier secuencia de caracteres que no sean palabras y guiones bajos en la cadena, ya que parecerían ser intencionales, por ejemplo, __HiThere_Guys convierte en __hi_there_guys .
  • Los sufijos de dígitos se consideran (intencionalmente) parte de la palabra, por ejemplo, NewVersion3 convierte en new_version3 .
  • Los prefijos de dígitos siguen a la caja original, por ejemplo, 3VersionsHere convierte en 3_versions_here , pero 3rdVersion convierte en 3rd_version .
  • Desafortunadamente, las siglas en mayúsculas de dos letras (por ejemplo, en IDNumber , donde ID se consideraría una palabra diferente), como se sugiere en las Convenciones de Capitalización de Microsoft , no son compatibles, ya que entran en conflicto con otros casos. Recomiendo, en general, resistir esta guía, ya que es una excepción aparentemente arbitraria a la convención de no capitalizar las siglas. Quédate con IdNumber .




regex