簡體   English   中英

我需要使用Java / RegEx從大型數據文件中的車輛描述字段中刪除〜50個顏色名稱,而無需使用數組或循環

[英]I need to remove ~50 color names from a vehicle description field in a large data file using Java/RegEx without arrays or loops

我正在使用一個數據集成工具,該工具允許Java幫助轉換數據。 問題是我不能創建數組或使用循環,因為不支持它們。

我的字段具有類似String的值:

04 Blue Honda Accord
12 Inferno Red Chevrolet Tahoe
10 Purple Ford Taurus

我只需要去除顏色即可:

04 Honda Accord
12 Chevrolet Tahoe
10 Ford Taurus

我唯一能想到的就是用49個顏色名稱創建一個正則表達式,但是我對regex相當不滿意。

更新以消除輸出中的多余空間(將(.+)更改為[SPACE](.+) )。

假設每輛車都在單獨的線路上,則可以這樣做:

^(\d+ )(?:Blue|Red|Purple|Inferno Red) (.+)$

正則表達式可視化

Debuggex演示

采用

sNumColorCarLine.replaceAll(sTheRegex, "$1$2");

要么

sNumColorCarLine.replaceFirst(sTheRegex, "$1$2");

進行替換。 但是,為了提高效率(尤其是在有很多數據行的情況下),請使用以下命令,這樣可以避免為每行重新編譯模式(並重新創建匹配器):

import  java.util.regex.Pattern;
import  java.util.regex.Matcher;

/**
   <P>{@code java RemoveColorFromCarLinesNoLoops}</P>
 **/
public class RemoveColorFromCarLinesNoLoops  {
   public static final void main(String[] igno_red)  {

      //Add colors as necessary
      String sColorsNonCaptureOr = "(?:Blue|Red|Purple|Inferno Red)";
      String sRegex = "" +
         "^(\\d+ )" +            //one-or-more digits, then one space
         sColorsNonCaptureOr +   //color
         " (.+)$";               //Everything after the color (space uncaptured)

      String sRplcWith = "$1$2";

         //"": Unused search-string, so matcher can be reused.
      Matcher m = Pattern.compile(sRegex).matcher("");

      String sColorRemoved1 = removeColorFromCarLine(m, "04 Blue Honda Accord", sRplcWith);
      String sColorRemoved2 = removeColorFromCarLine(m, "12 Inferno Red Chevrolet Tahoe", sRplcWith);
      String sColorRemoved3 = removeColorFromCarLine(m, "10 Purple Ford Taurus", sRplcWith);
   }
   private static final String removeColorFromCarLine(Matcher m_m, String s_origCarLine, String s_rplcWith)  {
      m_m.reset(s_origCarLine);
      if(!m_m.matches())  {
         throw  new IllegalArgumentException("Does not match: \"" + " + s_origCarLine + " + "\", pattern=[" + m_m.pattern() + "]");
      }

      //Since it matches(s), this is equivalent to "replace the entire line, as a whole"
      String s = m_m.replaceFirst(s_rplcWith);
      System.out.println(s_origCarLine + "  -->  " + s);
      return  s;
   }
}

輸出量

[C:\java_code\]java RemoveColorFromCarLinesNoLoops
04 Blue Honda Accord  -->  04 Honda Accord
12 Inferno Red Chevrolet Tahoe  -->  12 Chevrolet Tahoe
10 Purple Ford Taurus  -->  10 Ford Taurus

假設每個字段在形式digits colours description只有一個值digits colours description ou可以嘗試類似

text = text.replaceFirst("(?i)(?<=\\d)\\s(red|green|blue)\\b","");
  • (?i)將使正則表達式不區分大小寫,因此“紅色”將匹配“紅色”或“紅色”或“ ReD”,依此類推
  • (?<=\\\\d)將使用后退機制檢查實際匹配之前是否為數字
  • \\\\s表示空格
  • (red|green|blue)表示紅色或綠色或藍色
  • \\\\b代表單詞邊界,以檢查顏色是否不會成為描述中下一個單詞的一部分,例如greenhouses

順便說一句,如果您有一些顏色是其他一些顏色的一部分,例如graygray-red那么請務必在gray-red|gray之前放置最具體的gray-red|gray 這很重要,因為regex會嘗試根據從左到右的順序查找匹配項,因此,如果您的文本包含12 gray-red Mercedes並且您將使用replaceAll("gray|gray-red","")結果是12 -red Mercedes因為gray可以(並且)在gray-red之前匹配。

這樣,您無需指定顏色,並且可以在顏色名稱包含多個單詞的情況下使用:

String field = "12 Inferno Red Chevrolet Tahoe";
field = field.replaceFirst("(\\d+).*(\\w+\\s\\w+)", "$1 $2");
System.out.println(field);

印刷品:

12 Chevrolet Tahoe

正則表達式僅保留輸入的數字和最后兩個單詞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM