Sacar de elementos de formato de fecha cadena mediante una expresión regular

los cuales se determinen:

Quiero eliminar elementos A suministrado Cadena Formato de fecha - por ejemplo convertir el formato "dd / mm / aaaa" a "MM / aaaa" mediante la eliminación de cualquier no-M / elemento y.

Lo que estoy tratando de hacer es crear un formato localizada mes / año con base en el mes formato existente días / / año previsto para la configuración regional.

He hecho esto usando expresiones regulares, pero la solución parece más de lo que cabría esperar.

Un ejemplo es el siguiente:

public static void main(final String[] args) {
 System.out.println(filterDateFormat("dd/MM/yyyy HH:mm:ss", 'M', 'y'));
 System.out.println(filterDateFormat("MM/yyyy/dd", 'M', 'y'));
 System.out.println(filterDateFormat("yyyy-MMM-dd", 'M', 'y'));
}

/**
 * Removes {@code charsToRetain} from {@code format}, including any redundant
 * separators.
 */
private static String filterDateFormat(final String format, final char...charsToRetain) {
 // Match e.g. "ddd-"
 final Pattern pattern = Pattern.compile("[" + new String(charsToRetain) + "]+\\p{Punct}?");
 final Matcher matcher = pattern.matcher(format);

 final StringBuilder builder = new StringBuilder();

 while (matcher.find()) {
  // Append each match
  builder.append(matcher.group());
 }

 // If the last match is "mmm-", remove the trailing punctuation symbol
 return builder.toString().replaceFirst("\\p{Punct}$", "");
}
AVI:

Probemos una solución para las siguientes cadenas de formato de fecha:

String[] formatStrings = { "dd/MM/yyyy HH:mm:ss", 
                           "MM/yyyy/dd", 
                           "yyyy-MMM-dd", 
                           "MM/yy - yy/dd", 
                           "yyabbadabbadooMM" };

A continuación se analizará cuerdas para un partido, a continuación, imprimir el primer grupo del partido.

Pattern p = Pattern.compile(REGEX);
for(String formatStr : formatStrings) {
    Matcher m = p.matcher(formatStr);
    if(m.matches()) {
        System.out.println(m.group(1));
    }
    else {
        System.out.println("Didn't match!");
    }
}

Ahora, hay dos expresiones regulares separadas que he probado. Primero:

final String REGEX = "(?:[^My]*)([My]+[^\\w]*[My]+)(?:[^My]*)";

Con la salida del programa:

MM / aaaa
mm / aaaa
aaaa-MMM
no encontró!
No se han encontrado!

Segundo:

final String REGEX = "(?:[^My]*)((?:[My]+[^\\w]*)+[My]+)(?:[^My]*)";

Con la salida del programa:

MM / aaaa
mm / aaaa
aaaa-MMM
MM / aaaa
no encontró!

Ahora, vamos a ver lo que la primera expresión coincide en realidad a:

(?:[^My]*)([My]+[^\\w]*[My]+)(?:[^My]*) First regex =
(?:[^My]*)                              Any amount of non-Ms and non-ys (non-capturing)
          ([My]+                        followed by one or more Ms and ys
                [^\\w]*                 optionally separated by non-word characters
                                        (implying they are also not Ms or ys)
                       [My]+)           followed by one or more Ms and ys
                             (?:[^My]*) finished by any number of non-Ms and non-ys
                                        (non-capturing)

Lo que esto significa es que, al menos, 2 M / ys se requiere para que coincida con la expresión regular, aunque se debe tener cuidado de que algo así como MM-DD o yy-DD coincidirá así, porque tienen dos regiones M-o-y1 carácter largo. Se puede evitar meterse en problemas aquí sólo manteniendo una comprobación de validez en su cadena de formato de fecha, tales como:

if(formatStr.contains('y') && formatStr.contains('M') && m.matches())
{
    String yMString = m.group(1);
    ... // other logic
}

En cuanto a la segunda expresión regular, esto es lo que significa:

(?:[^My]*)((?:[My]+[^\\w]*)+[My]+)(?:[^My]*) Second regex =
(?:[^My]*)                                   Any amount of non-Ms and non-ys 
                                             (non-capturing)
          (                      )           followed by
           (?:[My]+       )+[My]+            at least two text segments consisting of
                                             one or more Ms or ys, where each segment is
                   [^\\w]*                   optionally separated by non-word characters
                                  (?:[^My]*) finished by any number of non-Ms and non-ys
                                             (non-capturing)

Esta expresión regular coincidirá con una serie de cadenas ligeramente más amplio, pero todavía requiere que cualquier separación entre la EM y ys ser no-palabras ( [^a-zA-Z_0-9]). Además, tenga en cuenta que esta expresión regular aún coincidirá con "aa", "MM", o cadenas similares como "yyy", "aaaa" ..., por lo que sería útil tener una comprobación de validez como se describe para el regular previo expresión.

Además, aquí hay un ejemplo rápido de cómo se podría utilizar lo anterior para manipular una cadena de formato fecha única:

LocalDateTime date = LocalDateTime.now();
String dateFormatString = "dd/MM/yyyy H:m:s";
System.out.println("Old Format: \"" + dateFormatString + "\" = " + 
    date.format(DateTimeFormatter.ofPattern(dateFormatString)));
Pattern p = Pattern.compile("(?:[^My]*)([My]+[^\\w]*[My]+)(?:[^My]*)");
Matcher m = p.matcher(dateFormatString);
if(dateFormatString.contains("y") && dateFormatString.contains("M") && m.matches())
{
    dateFormatString = m.group(1);
    System.out.println("New Format: \"" + dateFormatString + "\" = " + 
        date.format(DateTimeFormatter.ofPattern(dateFormatString)));
}
else
{
    throw new IllegalArgumentException("Couldn't shorten date format string!");
}

Salida:

Formato de edad: "dd / MM / aaaa h: m: s" = 14/08/2019 16:55:45
Nuevo Formato: "MM / aaaa" = 08/2019

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=313671&siteId=1
Recomendado
Clasificación