@Override
  public Writable doSerialize(Object obj, ObjectInspector objInspector)
      throws SerDeException {

    if (outputFormatString == null) {
      throw new SerDeException(
          "Cannot write data into table because \"output.format.string\""
          + " is not specified in serde properties of the table.");
    }

    // Get all the fields out.
    // NOTE: The correct way to get fields out of the row is to use
    // objInspector.
    // The obj can be a Java ArrayList, or a Java class, or a byte[] or
    // whatever.
    // The only way to access the data inside the obj is through
    // ObjectInspector.

    StructObjectInspector outputRowOI = (StructObjectInspector) objInspector;
    List<? extends StructField> outputFieldRefs = outputRowOI
        .getAllStructFieldRefs();
    if (outputFieldRefs.size() != numColumns) {
      throw new SerDeException("Cannot serialize the object because there are "
          + outputFieldRefs.size() + " fields but the table has " + numColumns
          + " columns.");
    }

    // Get all data out.
    for (int c = 0; c < numColumns; c++) {
      Object field = outputRowOI
          .getStructFieldData(obj, outputFieldRefs.get(c));
      ObjectInspector fieldOI = outputFieldRefs.get(c)
          .getFieldObjectInspector();
      // The data must be of type String
      StringObjectInspector fieldStringOI = (StringObjectInspector) fieldOI;
      // Convert the field to Java class String, because objects of String type
      // can be
      // stored in String, Text, or some other classes.
      outputFields[c] = fieldStringOI.getPrimitiveJavaObject(field);
    }

    // Format the String
    String outputRowString = null;
    try {
      outputRowString = String.format(outputFormatString, outputFields);
    } catch (MissingFormatArgumentException e) {
      throw new SerDeException("The table contains " + numColumns
          + " columns, but the outputFormatString is asking for more.", e);
    }
    outputRowText.set(outputRowString);
    return outputRowText;
  }
RegexSerDe uses regular expression (regex) to serialize/deserialize.

It can deserialize the data using regex and extracts groups as columns. It
can also serialize the row object using a format string.

In deserialization stage, if a row does not match the regex, then all columns
in the row will be NULL. If a row matches the regex but has less than
expected groups, the missing groups will be NULL. If a row matches the regex
but has more than expected groups, the additional groups are just ignored.

In serialization stage, it uses java string formatter to format the columns
into a row. If the output type of the column in a query is not a string, it
will be automatically converted to String by Hive.

For the format of the format String, please refer to link: http
://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html#syntax

NOTE: Obviously, all columns have to be strings. Users can use
"CAST(a AS INT)" to convert columns to other types.

NOTE: This implementation is using String, and javaStringObjectInspector. A
more efficient implementation should use UTF-8 encoded Text and
writableStringObjectInspector. We should switch to that when we have a UTF-8
based Regex library.
contrib/src/java/org/apache/hadoop/hive/contrib/serde2/RegexSerDe.java