How to replace matched character String in java? - java

I have a question about how to replace String when matched character found. In this case, i read java file that contains variable which marked with underscore. Here the java file:
public int[][] initArray(int rows, int cols, int init_value)
{
int[][] _bb = (int[][])null;
if ((rows > 1) && (cols > 1)) {
_bb = new int[rows][cols];
for (int _ii = 0; _ii < rows; _ii++) {
for (int _ee = 0; _ee < cols; _ee++) {
_bb[_ii][_ee] = init_value;
}
}
} else {
warning("Array length must be greater than zero!");
}
return _bb;
}
All of variable that contain underscore will be replaced with generate string. Well, then this is the code that i have used to read that file and replace matched string:
HashMap<String, String> map = new HashMap<String, String>();
if (line.contains(" _") && line.contains(";")) {
String get = varname(line);
RandomString r = new RandomString();
String[] split = get.split("\\s+");
String gvarname = split[0];
ss = "_"+gvarname;
map.put(ss, "l"+r.generateRandomString());
for(String key: map.keySet()){
if(line.contains(key)){
line = line.replace(key, map.get(key));
}
}
Then, this is a method to get an index of variable name:
String varname(String str){
int startIdx = str.indexOf("_");
int endIdx = str.indexOf(';');
String content = str.substring(startIdx + 1, endIdx);
return content;
}
Actually above code is working and replace some variables name, but some character noted matched when i put space example _bb[_ii] is not working, but _bb[ _ii ] is working. I don't know how, help me!
Thanks

Use regex to recognize the entire variable, here using \b to find word boundaries.
public class Obfuscate {
private static final Pattern VAR_PATTERN = Pattern.compile("\\b_(\\w+)\\b");
private final Map<String, String> renames = new HashMap<>();
public String obfuscate(String sourceCode) {
StringBuffer buf = new StringBuffer(sourceCode.length() + 100);
Matcher m = VAR_PATTERN.matcher(sourceCode);
while (m.find()) {
String var = m.group(1);
String newVar = renames.get(var);
if (newVar == null) {
newVar = randomVar();
renames.put(var, newVar);
}
m.appendReplacement(buf, newVar);
}
m.appendTail(buf);
return buf.toString();
}
}
A map is needed to match the same old variable to the same new name.
A Set<String> of new names might be needed to check that the generated name does not repeat.
Your approach of doing a replaceAll of the same var is fine too, but requires reading all. The method above can be repeated (say per line), hence the map as field.

In your first if-statement you check if the string contains " _" (an underscore with a leading space).
If in the following line of your source-java-file
_bb[_ii][_ee] = init_value;
_bb... is indented with tabulators, <tab>_bb will not match <space>_bb. There is no leading space before _ii and _ee either, so the if returns false.
If you put a space between [ and _ii, you find a match for <space>_ii and your if results in true and executes your replacement code.
If you are sure that there will be no other use of an underscore in your source text other than as a replacement indicator, you can simply remove the space from your if-condition and use line.contains("_") instead.
Btw: Are you sure that you want to check that the line must contain a ; aswell? What if your source text contains a line like while(_xx==true) {?
Also, because of
String[] split = get.split("\\s+");
String gvarname = split[0];
your code is not able to split a line like _bb[_ii][_ee] correctly (and even if it would be, because of split[0] you would only replace the first identifier you found, subsequent ones would be ignored). Your split searches for spaces and the source line doesn't contain any. Again, you could probably change this and split for underscores (this would return an array containing bb[, ii][ and ee]) and then loop every returned array element until you find the first character that can't be part of your variable identifier (e.g. until the first non-alphanumeric character).
An _ plus the part of the array element up to that non-alphanumeric character is then the identifier that you want to replace.

Related

Java regex: Replace all characters with `+` except instances of a given string

I have the following problem which states
Replace all characters in a string with + symbol except instances of the given string in the method
so for example if the string given was abc123efg and they want me to replace every character except every instance of 123 then it would become +++123+++.
I figured a regular expression is probably the best for this and I came up with this.
str.replaceAll("[^str]","+")
where str is a variable, but its not letting me use the method without putting it in quotations. If I just want to replace the variable string str how can I do that? I ran it with the string manually typed and it worked on the method, but can I just input a variable?
as of right now I believe its looking for the string "str" and not the variable string.
Here is the output its right for so many cases except for two :(
List of open test cases:
plusOut("12xy34", "xy") → "++xy++"
plusOut("12xy34", "1") → "1+++++"
plusOut("12xy34xyabcxy", "xy") → "++xy++xy+++xy"
plusOut("abXYabcXYZ", "ab") → "ab++ab++++"
plusOut("abXYabcXYZ", "abc") → "++++abc+++"
plusOut("abXYabcXYZ", "XY") → "++XY+++XY+"
plusOut("abXYxyzXYZ", "XYZ") → "+++++++XYZ"
plusOut("--++ab", "++") → "++++++"
plusOut("aaxxxxbb", "xx") → "++xxxx++"
plusOut("123123", "3") → "++3++3"
Looks like this is the plusOut problem on CodingBat.
I had 3 solutions to this problem, and wrote a new streaming solution just for fun.
Solution 1: Loop and check
Create a StringBuilder out of the input string, and check for the word at every position. Replace the character if doesn't match, and skip the length of the word if found.
public String plusOut(String str, String word) {
StringBuilder out = new StringBuilder(str);
for (int i = 0; i < out.length(); ) {
if (!str.startsWith(word, i))
out.setCharAt(i++, '+');
else
i += word.length();
}
return out.toString();
}
This is probably the expected answer for a beginner programmer, though there is an assumption that the string doesn't contain any astral plane character, which would be represented by 2 char instead of 1.
Solution 2: Replace the word with a marker, replace the rest, then restore the word
public String plusOut(String str, String word) {
return str.replaceAll(java.util.regex.Pattern.quote(word), "#").replaceAll("[^#]", "+").replaceAll("#", word);
}
Not a proper solution since it assumes that a certain character or sequence of character doesn't appear in the string.
Note the use of Pattern.quote to prevent the word being interpreted as regex syntax by replaceAll method.
Solution 3: Regex with \G
public String plusOut(String str, String word) {
word = java.util.regex.Pattern.quote(word);
return str.replaceAll("\\G((?:" + word + ")*+).", "$1+");
}
Construct regex \G((?:word)*+)., which does more or less what solution 1 is doing:
\G makes sure the match starts from where the previous match leaves off
((?:word)*+) picks out 0 or more instance of word - if any, so that we can keep them in the replacement with $1. The key here is the possessive quantifier *+, which forces the regex to keep any instance of the word it finds. Otherwise, the regex will not work correctly when the word appear at the end of the string, as the regex backtracks to match .
. will not be part of any word, since the previous part already picks out all consecutive appearances of word and disallow backtrack. We will replace this with +
Solution 4: Streaming
public String plusOut(String str, String word) {
return String.join(word,
Arrays.stream(str.split(java.util.regex.Pattern.quote(word), -1))
.map((String s) -> s.replaceAll("(?s:.)", "+"))
.collect(Collectors.toList()));
}
The idea is to split the string by word, do the replacement on the rest, and join them back with word using String.join method.
Same as above, we need Pattern.quote to avoid split interpreting the word as regex. Since split by default removes empty string at the end of the array, we need to use -1 in the second parameter to make split leave those empty strings alone.
Then we create a stream out of the array and replace the rest as strings of +. In Java 11, we can use s -> String.repeat(s.length()) instead.
The rest is just converting the Stream to an Iterable (List in this case) and joining them for the result
This is a bit trickier than you might initially think because you don't just need to match characters, but the absence of specific phrase - a negated character set is not enough. If the string is 123, you would need:
(?<=^|123)(?!123).*?(?=123|$)
https://regex101.com/r/EZWMqM/1/
That is - lookbehind for the start of the string or "123", make sure the current position is not followed by 123, then lazy-repeat any character until lookahead matches "123" or the end of the string. This will match all characters which are not in a "123" substring. Then, you need to replace each character with a +, after which you can use appendReplacement and a StringBuffer to create the result string:
String inputPhrase = "123";
String inputStr = "abc123efg123123hij";
StringBuffer resultString = new StringBuffer();
Pattern regex = Pattern.compile("(?<=^|" + inputPhrase + ")(?!" + inputPhrase + ").*?(?=" + inputPhrase + "|$)");
Matcher m = regex.matcher(inputStr);
while (m.find()) {
String replacement = m.group(0).replaceAll(".", "+");
m.appendReplacement(resultString, replacement);
}
m.appendTail(resultString);
System.out.println(resultString.toString());
Output:
+++123+++123123+++
Note that if the inputPhrase can contain character with a special meaning in a regular expression, you'll have to escape them first before concatenating into the pattern.
You can do it in one line:
input = input.replaceAll("((?:" + str + ")+)?(?!" + str + ").((?:" + str + ")+)?", "$1+$2");
This optionally captures "123" either side of each character and puts them back (a blank if there's no "123"):
So instead of coming up with a regular expression that matches the absence of a string. We might as well just match the selected phrase and append + the number of skipped characters.
StringBuilder sb = new StringBuilder();
Matcher m = Pattern.compile(Pattern.quote(str)).matcher(input);
while (m.find()) {
for (int i = 0; i < m.start(); i++) sb.append('+');
sb.append(str);
}
int remaining = input.length() - sb.length();
for (int i = 0; i < remaining; i++) {
sb.append('+');
}
Absolutely just for the fun of it, a solution using CharBuffer (unexpectedly it took a lot more that I initially hoped for):
private static String plusOutCharBuffer(String input, String match) {
int size = match.length();
CharBuffer cb = CharBuffer.wrap(input.toCharArray());
CharBuffer word = CharBuffer.wrap(match);
int x = 0;
for (; cb.remaining() > 0;) {
if (!cb.subSequence(0, size < cb.remaining() ? size : cb.remaining()).equals(word)) {
cb.put(x, '+');
cb.clear().position(++x);
} else {
cb.clear().position(x = x + size);
}
}
return cb.clear().toString();
}
To make this work you need a beast of a pattern. Let's say you you are operating on the following test case as an example:
plusOut("abXYxyzXYZ", "XYZ") → "+++++++XYZ"
What you need to do is build a series of clauses in your pattern to match a single character at a time:
Any character that is NOT "X", "Y" or "Z" -- [^XYZ]
Any "X" not followed by "YZ" -- X(?!YZ)
Any "Y" not preceded by "X" -- (?<!X)Y
Any "Y" not followed by "Z" -- Y(?!Z)
Any "Z" not preceded by "XY" -- (?<!XY)Z
An example of this replacement can be found here: https://regex101.com/r/jK5wU3/4
Here is an example of how this might work (most certainly not optimized, but it works):
import java.util.regex.Pattern;
public class Test {
public static void plusOut(String text, String exclude) {
StringBuilder pattern = new StringBuilder("");
for (int i=0; i<exclude.length(); i++) {
Character target = exclude.charAt(i);
String prefix = (i > 0) ? exclude.substring(0, i) : "";
String postfix = (i < exclude.length() - 1) ? exclude.substring(i+1) : "";
// add the look-behind (?<!X)Y
if (!prefix.isEmpty()) {
pattern.append("(?<!").append(Pattern.quote(prefix)).append(")")
.append(Pattern.quote(target.toString())).append("|");
}
// add the look-ahead X(?!YZ)
if (!postfix.isEmpty()) {
pattern.append(Pattern.quote(target.toString()))
.append("(?!").append(Pattern.quote(postfix)).append(")|");
}
}
// add in the other character exclusion
pattern.append("[^" + Pattern.quote(exclude) + "]");
System.out.println(text.replaceAll(pattern.toString(), "+"));
}
public static void main(String [] args) {
plusOut("12xy34", "xy");
plusOut("12xy34", "1");
plusOut("12xy34xyabcxy", "xy");
plusOut("abXYabcXYZ", "ab");
plusOut("abXYabcXYZ", "abc");
plusOut("abXYabcXYZ", "XY");
plusOut("abXYxyzXYZ", "XYZ");
plusOut("--++ab", "++");
plusOut("aaxxxxbb", "xx");
plusOut("123123", "3");
}
}
UPDATE: Even this doesn't quite work because it can't deal with exclusions that are just repeated characters, like "xx". Regular expressions are most definitely not the right tool for this, but I thought it might be possible. After poking around, I'm not so sure a pattern even exists that might make this work.
The problem in your solution that you put a set of instance string str.replaceAll("[^str]","+") which it will exclude any character from the variable str and that will not solve your problem
EX: when you try str.replaceAll("[^XYZ]","+") it will exclude any combination of character X , character Y and character Z from your replacing method so you will get "++XY+++XYZ".
Actually you should exclude a sequence of characters instead in str.replaceAll.
You can do it by using capture group of characters like (XYZ) then use a negative lookahead to match a string which does not contain characters sequence : ^((?!XYZ).)*$
Check this solution for more info about this problem but you should know that it may be complicated to find regular expression to do that directly.
I have found two simple solutions for this problem :
Solution 1:
You can implement a method to replace all characters with '+' except the instance of given string:
String exWord = "XYZ";
String str = "abXYxyzXYZ";
for(int i = 0; i < str.length(); i++){
// exclude any instance string of exWord from replacing process in str
if(str.substring(i, str.length()).indexOf(exWord) + i == i){
i = i + exWord.length()-1;
}
else{
str = str.substring(0,i) + "+" + str.substring(i+1);//replace each character with '+' symbol
}
}
Note : str.substring(i, str.length()).indexOf(exWord) + i this if statement will exclude any instance string of exWord from replacing process in str.
Output:
+++++++XYZ
Solution 2:
You can try this Approach using ReplaceAll method and it doesn't need any complex regular expression:
String exWord = "XYZ";
String str = "abXYxyzXYZ";
str = str.replaceAll(exWord,"*"); // replace instance string with * symbol
str = str.replaceAll("[^*]","+"); // replace all characters with + symbol except *
str = str.replaceAll("\\*",exWord); // replace * symbol with instance string
Note : This solution will work only if your input string str doesn't contain any * symbol.
Also you should escape any character with a special meaning in a regular expression in phrase instance string exWord like : exWord = "++".

Replace words in parenthesis

I have a question about replacing words. I have some strings, each of which looks like this:
String string = "today is a (happy) day, I would like to (explore) more about Java."
I need to replace the words that have parentheses. I want to replace "(happy)" with "good", and "(explore)" with "learn".
I have some ideas, but I don't know how.
for (int i = 0; i <= string.length(), i++) {
for (int j = 0; j <= string.length(), j++
if ((string.charAt(i)== '(') && (string.charAt(j) == ')')) {
String w1 = line.substring(i+1,j);
string.replace(w1, w2)
}
}
}
My problem is that I can only replace one word with one new word...
I am thinking of using a scanner to prompt me to give a new word and then replace it, how can I do this?
The appendReplacement and appendTail methods of Matcher are designed for this purpose. You can use a regex to scan for your pattern--a pair of parentheses with a word in the middle--then do whatever you need to do to determine the string to replace it with. See the javadoc.
An example, based on the example in the javadoc. I'm assuming you have two methods, replacement(word) that tells what you want to replace the word with (so that replacement("happy") will equal "good" in your example), and hasReplacement(word) that tells whether the word has a replacement or not.
Pattern p = Pattern.compile("\\((.*?)\\)");
Matcher m = p.matcher(source);
StringBuffer sb = new StringBuffer();
while (m.find()) {
String word = m.group(1);
String newWord = hasReplacement(word) ? replacement(word) : m.group(0);
m.appendReplacement(sb, newWord); // appends the replacement, plus any not-yet-used text that comes before the match
}
m.appendTail(sb); // appends any text left over after the last match
String result = sb.toString();
Use below code for replacing the string.
String string = "today is a (happy) day, I would like to (explore) more about Java.";
string = string.replaceAll("\\(happy\\)", "good");
string = string.replaceAll("\\(explore\\)", "learn");
System.out.println(string);`
What you can do is run a loop from 0 to length-1 and if loop encounters a ( then assign its index to a temp1 variable. Now go on further as long as you encounter ).Assign its index to temp2 .Now you can replace that substring using string.replace(string.substring(temp1+1,temp2),"Your desired string")).
No need to use the nested loops. Better use one loop and store the index when you find opening parenthesis and also for close parenthesis and replace it with the word. Continue the same loop and store next index. As you are replacing the words in same string it changes the length of string you need to maintain copy of string and perform loop and replace on different,
Do not use nested for loop. Search for occurrences of ( and ). Get the substring between these two characters and then replace it with the user entered value. Do it till there are not more ( and ) combinations left.
import java.util.Scanner;
public class ReplaceWords {
public static String replaceWords(String s){
while(s.contains(""+"(") && s.contains(""+")")){
Scanner keyboard = new Scanner(System.in);
String toBeReplaced = s.substring(s.indexOf("("), s.indexOf(")")+1);
System.out.println("Enter the word with which you want to replace "+toBeReplaced+" : ");
String replaceWith = keyboard.nextLine();
s = s.replace(toBeReplaced, replaceWith);
}
return s;
}
public static void main(String[] args) {
String myString ="today is a (happy) day, I would like to (explore) more about Java.";
myString = replaceWords(myString);
System.out.println(myString);
}
}
This snippet works for me, just load the HashMap up with replacements and iterate through:
import java.util.*;
public class Test
{
public static void main(String[] args) {
String string = "today is a (happy) day, I would like to (explore) more about Java.";
HashMap<String, String> hm = new HashMap<String, String>();
hm.put("\\(happy\\)", "good");
hm.put("\\(explore\\)", "learn");
for (Map.Entry<String, String> entry : hm.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
string = string.replaceAll(key, value);
}
System.out.println(string);
}
}
Remember, replaceAll takes a regex, so you want it to display "\(word\)", which means the slashes themselves must be escaped.

Remove trailing substring from String in Java

I am looking to remove parts of a string if it ends in a certain string.
An example would be to take this string: "am.sunrise.ios#2x.png"
And remove the #2x.png so it looks like: "am.sunrise.ios"
How would I go about checking to see if the end of a string contains "#2x.png" and remove it?
You could check the lastIndexOf, and if it exists in the string, use substring to remove it:
String str = "am.sunrise.ios#2x.png";
String search = "#2x.png";
int index = str.lastIndexOf(search);
if (index > 0) {
str = str.substring(0, index);
}
Assuming you have a string initialized as String file = "am.sunrise.ios#2x.png";.
if(file.endsWith("#2x.png"))
file = file.substring(0, file.lastIndexOf("#2x.png"));
The endsWith(String) method returns a boolean determining if the string has a certain suffix. Depending on that you can replace the string with a substring of itself starting with the first character and ending before the index of the character that you are trying to remove.
private static String removeSuffixIfExists(String key, String suffix) {
return key.endswith(suffix)
? key.substring(0, key.length() - suffix.length())
: key;
}
}
String suffix = "#2x.png";
String key = "am.sunrise.ios#2x.png";
String output = removeSuffixIfExists(key, suffix);
public static void main(String [] args){
String word = "am.sunrise.ios#2x.png";
word = word.replace("#2x.png", "");
System.out.println(word);
}
If you want to generally remove entire content of string from # till end you can use
yourString = yourString.replaceAll("#.*","");
where #.* is regex (regular expression) representing substring starting with # and having any character after it (represented by .) zero or more times (represented by *).
In case there will be no #xxx part your string will be unchanged.
If you want to change only this particular substring #2x.png (and not substirng like #3x.png) while making sure that it is placed at end of your string you can use
yourString = yourString.replaceAll("#2x\\.png$","");
where
$ represents end of string
\\. represents . literal (we need to escape it since like shown earlier . is metacharacter representing any character)
Since I was trying to do this on an ArrayList of items similarly styled I ended up using the following code:
for (int image = 0; image < IBImages.size(); image++) {
IBImages.set(image, IBImages.get(image).split("~")[0].split("#")[0].split(".png")[0]);
}
If I have a list of images with the names
[am.sunrise.ios.png, am.sunrise.ios#2x.png, am.sunrise.ios#3x.png, am.sunrise.ios~ipad.png, am.sunrise.ios~ipad#2x.png]
This allows me to split the string into 2 parts.
For example, "am.sunrise.ios~ipad.png" will be split into "am.sunrise.ios" and "~ipad.png" if I split on "~". I can just get the first part back by referencing [0]. Therefore I get what I'm looking for in one line of code.
Note that image is "am.sunrise.ios~ipad.png"
You could use String.split():
public static void main(String [] args){
String word = "am.sunrise.ios#2x.png";
String[] parts = word.split("#");
if (parts.length == 2) {
System.out.println("looks like user#host...");
System.out.println("User: " + parts[0]);
System.out.println("Host: " + parts[1]);
}
}
Then you haven an array of Strings, where the first element contains the part before "#" and the second element the part after the "#".
Combining the answers 1 and 2:
String str = "am.sunrise.ios#2x.png";
String search = "#2x.png";
if (str.endsWith(search)) {
str = str.substring(0, str.lastIndexOf(search));
}

Simplify & condense multiple editorial operations on an array. Java

I have some raw output that I want to clean up and make presentable but right now I go about it in a very ugly and cumbersome way, I wonder if anyone might know a clean and elegant way in which to perform the same operation.
int size = charOutput.size();
for (int i = size - 1; i >= 1; i--)
{
if(charOutput.get(i).compareTo(charOutput.get(i - 1)) == 0)
{
charOutput.remove(i);
}
}
for(int x = 0; x < charOutput.size(); x++)
{
if(charOutput.get(x) == '?')
{
charOutput.remove(x);
}
}
String firstOne = Arrays.toString(charOutput.toArray());
String secondOne = firstOne.replaceAll(",","");
String thirdOne = secondOne.substring(1, secondOne.length() - 1);
String output = thirdOne.replaceAll(" ","");
return output;
ZouZou has the right code for fixing the final few calls in your code. I have some suggestions for the for loops. I hope I got them right...
These work after you get the String represented by charOutput, using a method such as the one suggested by ZouZou.
Your first block appears to remove all repeated letters. You can use a regular expression for that:
Pattern removeRepeats = Pattern.compile("(.)\\1{1,}");
// "(.)" creates a group that matches any character and puts it into a group
// "\\1" gets converted to "\1" which is a reference to the first group, i.e. the character that "(.)" matched
// "{1,}" means "one or more"
// So the overall effect is "one or more of a single character"
To use:
removeRepeats.matcher(s).replaceAll("$1");
// This creates a Matcher that matches the regex represented by removeRepeats to the contents of s, and replaces the parts of s that match the regex represented by removeRepeats with "$1", which is a reference to the first group captured (i.e. "(.)", which is the first character matched"
To remove the question mark, just do
Pattern removeQuestionMarks = Pattern.compile("\\?");
// Because "?" is a special symbol in regex, you have to escape it with a backslash
// But since backslashes are also a special symbol, you have to escape the backslash too.
And then to use, do the same thing as was done above except with replaceAll("");
And you're done!
If you really wanted to, you can combine a lot of regex into two super-regex expressions (and one normal regex expression):
Pattern p0 = Pattern.compile("(\\[|\\]|\\,| )"); // removes brackets, commas, and spaces
Pattern p1 = Pattern.compile("(.)\\1{1,}"); // Removes duplicate characters
Pattern p2 = Pattern.compile("\\?");
String removeArrayCharacters = p0.matcher(charOutput.toString()).replaceAll("");
String removeDuplicates = p1.matcher(removeArrayCharacters).replaceAll("$1");
return p2.matcher(removeDuplicates).replaceAll("");
Use a StringBuilder and append each character you want, at the end just return myBuilder.toString();
Instead of this:
String firstOne = Arrays.toString(charOutput.toArray());
String secondOne = firstOne.replaceAll(",","");
String thirdOne = secondOne.substring(1, secondOne.length() - 1);
String output = thirdOne.replaceAll(" ","");
return output;
Simply do:
StringBuilder sb = new StringBuilder();
for(Character c : charOutput){
sb.append(c);
}
return sb.toString();
Note that you are doing a lot of unnecessary work (by iterating through the list and removing some elements). What you can actually do is just iterate one time and then if the condition fullfits your requirements (the two adjacent characters are not the same and no question mark) then append it to the StringBuilder directly.
This task could also be a job for a regular expression.
If you don't want to use Regex try this version to remove consecutive characters and '?':
int size = charOutput.size();
if (size == 1) return Character.toString((Character)charOutput.get(0));
else if (size == 0) return null;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < size - 1; i++) {
Character temp = (Character)charOutput.get(i);
if (!temp.equals(charOutput.get(i+1)) && !temp.equals('?'))
sb.append(temp);
}
//for the last element
if (!charOutput.get(size-1).equals(charOutput.get(size-2))
&& !charOutput.get(size-1).equals('?'))
sb.append(charOutput.get(size-1));
return sb.toString();

How to remove all the punctuation except whitespaces or numbers in java

How to remove all the punctuation except whitespaces or numbers in Java.
"\\p{Punct}|\\d", "" //THIS WORKS BUT IT REMOVES THE NUMBERS AND I DONT WANT IT TO REMOVE THE NUMBERS...
I am reading text and I need to remove punctuation.
String[] internal;
char ch = 'a';
int counter = 1;
int count;
int c;
Map<String, Set> dictionary = new HashMap<String, Set>();
BufferedReader in = new BufferedReader(new FileReader("yu.txt"));
while (in.ready()) {
internal = (((in.readLine()).replaceAll("\\p{Punct}|\\d", "")).toLowerCase()).split(" ");//this does not work in my case cause it removes numbers... and makes them whitespaces but other than that this one works I JUST dont want it to remove numbers and keep whitespaces...
for (count = 0; count < internal.length; count++) {
if (!dictionary.containsKey(internal[count])) {
dictionary.put(internal[count], new HashSet());
}
if (dictionary.get(internal[count]).size()<10)
{
dictionary.get(internal[count]).add(counter);
}
}
counter++;
}
Iterator iterator = dictionary.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next().toString();
String value = dictionary.get(key).toString();
System.out.println(key + ": " + value );
}
str = str.replaceAll("[^0-9a-zA-Z\s]", "X");
I am unaware of an existing class (default) which can do so.
You will need to write a logic that goes through the String character by character and check if the character is a punctuation. If its is, then cut the String one char before and append the remaining part (effectively removing that char/punctuation).
Prefer using a StringBuilder or StringBuffer instead of directly manipulating the String.
Use the String.substring() method to cut the string.
Else use the String.replace()/String.replaceAll() method to replace all punctuation (you will need to escape certain characters) with "".

Categories

Resources