当前位置: 首页 > 知识库问答 >
问题:

使用正则表达式从日期格式字符串中删除元素

穆俊哲
2023-03-14

我想删除提供的日期格式字符串的元素-例如通过删除任何非M/y元素将格式“dd/MM/yyyy”转换为“MM/yyyy”。

我尝试做的是基于为该地区提供的现有日/月/年格式创建本地化的月/年格式。

我已经使用正则表达式完成了这项工作,但解决方案似乎比我预期的要长。

示例如下:

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}$", "");
}

共有2个答案

岑鸣
2023-03-14

我将试着用对我的问题的理解来回答:我如何从一个字符串的列表/表格/数组中移除不完全遵循模式“dd/MM”的元素?

所以我在寻找一个看起来像

public List<String> removeUnWantedDateFormat(List<String> input)

根据我对Dateformat的了解,我们可以预期只有4种你想要的可能性,希望我不会错过任何一种,它们是“MM/yyyy”,“MMM/yyyy”,“MM/yyy”,“MM/yyyy”。这样我们就知道我们正在寻找什么,我们可以做一个简单的功能。

public List<String> removeUnWantedDateFormat(List<String> input) {
  String s1 = "MM/yyyy";
  string s2 = "MMM/yyyy";
  String s3 = "MM/yy";
  string s4 = "MMM/yy";

  for (String format:input) {
    if (!s1.equals(format) && s2.equals(format) && s3.equals(format) && s4.equals(format))
      input.remove(format);
  }
  return input;
}

如果可以的话,最好不要使用正则html" target="_blank">表达式,这会花费很多资源。巨大的改进将是使用你接受的日期格式的枚举,就像这样,你可以更好地控制它,甚至替换它们。

希望这会有帮助,干杯

编辑:在我看到评论后,我认为最好使用contains而不是equals,应该像魅力一样工作,而不是remove,

输入=预期的字符串。

所以看起来更像是:

public List<String> removeUnWantedDateFormat(List<String> input) {
  List<String> comparaisons = new ArrayList<>();
  comparaison.add("MMM/yyyy");
  comparaison.add("MMM/yy");
  comparaison.add("MM/yyyy");
  comparaison.add("MM/yy");

  for (String format:input) {
    for(String comparaison: comparaisons)
      if (format.contains(comparaison)) {
      format = comparaison;
      break;
    }
  }
  return input;
}
冯俊英
2023-03-14

让我们尝试以下日期格式字符串的解决方案:

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

下面将分析匹配的字符串,然后打印匹配的第一组。

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!");
    }
}

现在,我尝试了两个独立的正则表达式。第一:

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

具有程序输出:

MM/yyyy
MM/YYY
yyyy MMM
不匹配<不匹配!

第二:

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

具有程序输出:

MM/
yyyy MM/yyyy
yyyy-MMM
MM/yy - yy
不匹配!

现在,让我们看看第一个正则表达式实际匹配的内容:

(?:[^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)

这意味着至少需要2 M/ys来匹配正则表达式,尽管您应该小心MM-dd或yy-DD之类的东西也会匹配,因为它们有两个1个字符长的M-or-y区域。您可以通过对日期格式字符串进行健全性检查来避免在这里遇到麻烦,例如:

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

至于第二个正则表达式,它的意思是:

(?:[^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)

这个正则表达式将匹配一系列稍宽的字符串,但它仍然要求Ms和ys之间的任何分隔符都是非字([^a-zA-Z_0-9])。此外,请记住,该正则表达式仍将匹配“yy”、“MM”或类似的字符串,如“yyy”、“yyy”…,因此,如前一个正则表达式所述,进行健全性检查将非常有用。

此外,这里有一个简单的例子,说明如何使用上面的方法来操作单个日期格式字符串:

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!");
}

输出:

旧格式:“DD/MM/yyyy H:m:s”= 14/08/2019 16:55:45 < br >新格式:“MM/yyyy”= 08/2019

 类似资料:
  • 问题内容: 如何在Java中从给定的字符串中删除所有方括号(“ []”)? 在这种情况下将使用什么正则表达式? 问题答案: 使用这个:

  • 问题内容: 我需要从此字符串中提取日期: BB通知:在04/10的11:28购买您的壁虱,最终卡号xxxx,$ 00,00。如果您不认识,请致电40032 2412。 也是整个日期04/04/2015 日期格式为dd / MM或dd / MM / yyyy 代码: String mydata =“ BB告知:在04/10的11:28,购买您的tickect,最终卡号xxxx,$ 00,00。如果您

  • 问题内容: 有什么方法可以使用正则表达式将字符串格式化为特定模式,还是stringbuilder +子字符串是一种更快的方法? 例如,说出电话号码-> 1234567890作为输入 并输出为->(123)456-7890 我看到有可能在这篇文章上:http : //www.4guysfromrolla.com/webtech/031302-1.shtml,但给出的解释在ASP中。我如何用Java做

  • 主要内容:实例下表包含了元字符的完整列表以及它们在正则表达式上下文中的行为: 字符 描述 \ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。 ^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或

  • 我在一个多语言网站上工作,并已选择使用每种语言的自定义URL,例如: 两者都指向城市控制员的指数方法。 在每个页面上都有一个切换语言的选项,它会在我的路由中查找以匹配控制器、视图和语言。 因此,如果我在荷兰语页面上,它会找到英文版的正确网址,即“城市”而不是“steden”。 在我开始使用更复杂的正则表达式之前,一切都很好。 我有这些正则表达式,它们将匹配我所需的URL: 在我的代码中,我可以访问

  • 问题内容: 假设我想使用正则表达式删除字符串中的所有重复字符(特定字符)。这很简单- 如果我想用相应的字符替换所有重复的字符(即a,z)怎么办?我该怎么做呢? 注意: 我知道可以使用哈希表或某些O(n ^ 2)算法更好地解决这种删除重复项的方法,但是我想使用正则表达式进行探索 问题答案: 的周围的指定 捕获组 ,然后将(一个 反向引用 在图案和替换两者)指的是第一个捕获组的内容。 因此,正则表达式