• Post Reply Bookmark Topic Watch Topic
  • New Topic

Masking of number in a string  RSS feed

 
Dinesh Kumar Behera
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi All,

I am new to java and need some help.
My requirement is to
1- mask the number(whose length is between 10 to 12).
2- central digits are replaced by 'X' and 1st and last two digits remains unchanged

Input string: dsfjgjkdfgjdsfjg12345678901fdgkhfdklg55555hfdkhg
output string: dsfjgjkdfgjdsfjg12XXXXXXX1fdgkhfdklg55555hfdkhg

In the above example number 123456789012 is masked to 12XXXXXX01 but the number 55555 remains same as length of 55555 is 5 and we will only mask the number whose length is between 10 to 12 .

Can anybody please guide me for the same.

By reading some blogs and documents I came to know that it can be possible by using regular expression. But unable to proceed further.

Kindly help !!!


Thank You,
Dinesh
 
E Armitage
Rancher
Posts: 989
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Show some effort and post some code that you have tried explaining where you got stuck.
 
Richard Tookey
Bartender
Posts: 1166
17
Java Linux Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The task can be done with one regular expression and one line using String.replaceAll() (or String.replaceFirst() if you only want to mask one per line) but it is not trivial and involves look behind and look ahead to deal with the junctions between the non-digits and digits. If this is as a homework assignment then I would suspect that you are not expected to use regular expressions and that you should just write a simple parser. If you are going to use regular expressions then take a look at http://docs.oracle.com/javase/tutorial/essential/regex/ and http://www.regular-expressions.info/tutorial.html .
 
Campbell Ritchie
Marshal
Posts: 56527
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch
Dinesh Kumar Behera wrote: . . . output string: dsfjgjkdfgjdsfjg12XXXXXXX1fdgkhfdklg55555hfdkhg

In the above example number 123456789012 is masked to 12XXXXXX01 . . .
No it isn't. I presume you have made a mistake copying it out, missing the 0. Please show is the correct forms.

Are you looking for 6‑8 digits preceded and succeeded by two digits each? I may be mistaken, but that might be a context‑sensitive grammar, in which case a regular expression will not work. Regular expressions can be complicated and error‑prone, so I suggest you try a different method. As E Armitage has said, please show us what you have achieved so far.
 
Campbell Ritchie
Marshal
Posts: 56527
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In which case I was mistaken, if you can use look forward and look behind. Agree with RT that it is much easier to write your own parser.
 
Richard Tookey
Bartender
Posts: 1166
17
Java Linux Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
On first reading this thread I created a test harness for it using String.replaceAll(); it took me all of 1 minute. Just out of interest I have just spend 20 minutes writing the same thing but without using regex and it looks horrendous! I'm not saying that the code for my non-regex approach is optimum (I'm sure it could be improved upon) nor am I saying that regex is the best solution since the learning curve is very very steep and the result esoteric but it does illustrate to me the power of regular expressions.

And for those who ask - arr but is the regex solution maintainable? In my view yes but I suspect few will agree.
 
Campbell Ritchie
Marshal
Posts: 56527
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Put it into a StringBuilder.
Count digits; when you get to the 10th and one of the next two characters is not a digit, you have found the String to replace. You simply have to work out whether to insert 6 or 7 Xs.
 
Richard Tookey
Bartender
Posts: 1166
17
Java Linux Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:Put it into a StringBuilder.
Count digits; when you get to the 10th and one of the next two characters is not a digit, you have found the String to replace. You simply have to work out whether to insert 6 or 7 Xs.


Very similar to my implementation but, unless I have misunderstood the specification, if there are more than 12 numeric chars you don't apply the mask.

Note - the OP's example is not consistent with the last two digits being unchanged since only the last digit is unchanged. My Java function would be easy to modify but the regex approach could be more problematic.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Richard Tookey wrote:The task can be done with one regular expression and one line using String.replaceAll() (or String.replaceFirst() if you only want to mask one per line) but it is not trivial and involves look behind and look ahead to deal with the junctions between the non-digits and digits.



Interesting. I am not sure if it is even possible to (1) check to make sure it is 12 digits or more, and (2) replace the digits with "X", but (2a) not replace the first digit, and (2b) not replace the last digit -- with a single regex and single replaceAll() call.... but I would be very interesting to know how it is done, if I am wrong.

BTW, I would likely use a single iteration loop and using appendReplacement()/appendTail() to accomplish this.

Henry
 
Richard Tookey
Bartender
Posts: 1166
17
Java Linux Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:
Richard Tookey wrote:The task can be done with one regular expression and one line using String.replaceAll() (or String.replaceFirst() if you only want to mask one per line) but it is not trivial and involves look behind and look ahead to deal with the junctions between the non-digits and digits.



Interesting. I am not sure if it is even possible to (1) check to make sure it is 12 digits or more, and (2) replace the digits with "X", but (2a) not replace the first digit, and (2b) not replace the last digit -- with a single regex and single replaceAll() call.... but I would be very interesting to know how it is done, if I am wrong.

BTW, I would likely use a single iteration loop and using appendReplacement()/appendTail() to accomplish this.

Henry


Having re-read the OP several more times and since the examples do not seem to agree with my latest interpretation of the wording I am no longer sure what the requirement is. Therefore until the OP comes back to clarify the requirement I will withdraw my assertion that it can be done with one replaceAll() . Once more I have stuck my foot in my mouth!

I would be interest in hearing from the OP what the result should be for these test cases.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Richard Tookey wrote:
Having re-read the OP several more times and since the examples do not seem to agree with my latest interpretation of the wording I am no longer sure what the requirement is. Therefore until the OP comes back to clarify the requirement I will withdraw my assertion that it can be done with one replaceAll() . Once more I have stuck my foot in my mouth!


It looks like I probably should do a better job at reading... it looks like the length should be "between 10 and 12" instead of "at least 12". With the limited range to check, it should be possible to do it with one regex and one replaceAll() call. Sorry for the confusion.

Henry
 
Richard Tookey
Bartender
Posts: 1166
17
Java Linux Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:
It looks like I probably should do a better job at reading... it looks like the length should be "between 10 and 12" instead of "at least 12". With the limited range to check, it should be possible to do it with one regex and one replaceAll() call.


On first reading the OP I formed a view of the requirement and my second and third readings did not change that view. At that point I was convinced that the requirement could be met using regular expressions with replaceAll()( or replaceFirst() if the OP only wanted to mask the first instance on a line). I very quickly knocked up two replaceAll() examples that used similar approaches but differed in detail.

Your previous post prompted me to re-visit the OP and I noted that in the desired output "dsfjgjkdfgjdsfjg12XXXXXXX1fdgkhfdklg55555hfdkhg" there were only 7 'X' and in my view of the requirement there needed to be 8 ! Ouch ! I then re-read the OP several times and found 2 other possible views of the requirement both of which made the use of replaceAll() difficult if not impossible.

I still think my original view is what the OP desired but I am no longer confident enough to assert that the task can be solved with replaceAll().
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!