0

I want to remove the non-printable character only for the String fields in the poject, I know we can use

public String removeNonPrintable(String field) {
    return field.replaceAll("[^A-Za-z0-9]", "");
}

to remove the non-printable characters from string.

But I want to have the generic method like:

public <T> T removeNonPrintable(Class<T> myClassObject) {
    /// Get only the string and remove non-printable code stuffs
    return removedNonPrintableCharactersmyClassObject;
}

Can anyone please help me to do it?

This question may be duplicate, but I failed to found the exact solutions for it.

kaviya .P
  • 469
  • 3
  • 11
  • 27
  • 1
    Is `[A-Za-z0-9]` your final definition of printable characters? How about other symbols (`./,"@$#!%^*&` etc)? – ernest_k Sep 11 '18 at 05:03
  • 1
    Why do you return ```T``` instead of ```String```? Or do you mean you want to modify the ```myClassObject``` to make its ```toString``` method return only printable characters? – zhh Sep 11 '18 at 05:08
  • @ernest_k I just posted it as an sample, will updated that function based on my requirement. Can you please suggest me , how can I do it for the entire pojo instead of the single fields. – kaviya .P Sep 11 '18 at 05:33
  • @kaviya.P It seems you have other option than reflection. Make the method take an object. And use the object's class to look for string fields and dynamically set their values after transforming the text – ernest_k Sep 11 '18 at 05:35
  • @zhh I want to have the myclass object in return, by removing all the unprintable characters from the string field. – kaviya .P Sep 11 '18 at 05:38
  • 1
    Read how to [Get all fields (even private and inherited) from class](https://stackoverflow.com/questions/16295949/get-all-fields-even-private-and-inherited-from-class) and how to [Changing private final fields via reflection](https://stackoverflow.com/questions/4516381/changing-private-final-fields-via-reflection) – LuCio Sep 11 '18 at 06:22

3 Answers3

0

You could use reflection, which would be problematic and not guaranteed to work for fields that have deep structures.

Or you could just run the instance through your code:

public String removeNonPrintable(Object obj) {
    return String.valueOf(obj).replaceAll("[^A-Za-z0-9]", "");
}

Note: String.valueOf() is used to avoid having to deal with obj being null.

You might have more success if you changed the transformation to:

replaceAll("[^ -~]", "")

which will remove everything not a "regular" ascii char (ie between decimal 32 and 126 inclusive).

Bohemian
  • 412,405
  • 93
  • 575
  • 722
0

Following is working:

public static void removeNonPrintable(Node node) throws NoSuchFieldException, IllegalAccessException{
        Field[] fields = Node.class.getDeclaredFields();
        for(int i=0;i<fields.length;i++){
            if(fields[i].getType().equals(String.class)) {
                fields[i].set(node, removeNonPrintable(fields[i].get(node).toString()));
                System.out.println(fields[i].get(node));
            }
        }
    }

class Node{
     String left;
     String right;
     int data;
    public Node(String left, String right, Integer data){
        this.left = left;
        this.right = right;
        this.data = data;
    }
}

It will work for a particular class(e.g. Node). I am trying to make it work with Class<T> but it's giving some exception right now.

mukesh210
  • 2,792
  • 2
  • 19
  • 41
0

You can do it using reflection, but it is not recommended:-

public static void main(String[] args) throws IllegalAccessException {
    Person person = new Person();
    person.setName("John***");
    person.setAge(12);

    final Field[] fields = person.getClass().getDeclaredFields();
    for (Field field : fields) {
        if (field.getType() == String.class) {
            field.set(person, removeNonPrintable((String) field.get(person)));
        }
    }
    System.out.println(person.getName());
    System.out.println(person.getAge());
}

//using the regex provided by OP
private static String removeNonPrintable(String s) {
    return s.replaceAll("[^A-Za-z0-9]", "");
}

And you'll have to change String fields to public accessor. This prints:-

John
12

A better approach is to do this in getters or setters of String fields.

Example:-

public String getName() {
    return removeNonPrintable(name);
}

OR

public void setName(String name) {
    this.name = removeNonPrintable(name);
}
Kartik
  • 7,677
  • 4
  • 28
  • 50