im finding a problem when doing a replace special characters using the replaceAll method.
i have this piece of code:
public static String replaceSpecialCharacters(String cadena) {
cadena = cadena.replaceAll("[âãáàä]", "a");
cadena = cadena.replaceAll("[ÂÃÁÀÄ]", "A");
cadena = cadena.replaceAll("[éèêë]", "e");
cadena = cadena.replaceAll("[ÉÈÊË]", "E");
cadena = cadena.trim();
return cadena;
}
when a string like "Álamont" fot instance comes, the method returns right the string "Alamont", however this string returned in the replace is not the same than "Alamont", first if I see the count attribute of the string it says its "8" instead of "7"....and if I tri to do:
if (cadena.equalsIgnoreCase("Alamont")) {
System.out.println("i've got ya!!");
}
it nevers goes in...im sure the problemas is in the replace character...can someone help me??
thanks a lot in advance
You should cleanup your question. It’s not clear, what you mean with “the method returns right the string "Alamont", however this string returned in the replace is not the same than "Alamont" ”, and it is not clear why you are surprised that the returned String might have a different length if you use trim or why you expect "Alamont" to be equal to "atico".
However, removing accents and other diacritical marks in a String can be easier than performing dozens of replace operations and risking to forget one:
import java.text.Normalizer;
…
s=Normalizer.normalize(s, Normalizer.Form.NFD)
.replaceAll("\\p{InCombiningDiacriticalMarks}", "");
This sounds suspiciously like your input values are using combining characters. There's nothing wrong with this, but you should expect the String length to change.
There are ways to normalize your strings to use the non-combining version of the character ... but I forget.... there it is, Normalization tutorial ... that link is causing my browser (firefox, in ie it works better) to slow down, but it is the real link!... maybe the Normalizer JavaDoc will be enough
Related
I want to encrypt the password when it shows out in registration report, instead of showing the real password I would like to encrypt all the value to an asterisk (*) I tried to replace all character one-by-one to asterisk * but I think that is not the right way to achieve the result.
String s1="mypassword";
String replaceString=s1.replaceAll("a","*");
replaceString=s1.replaceAll("b","*");
replaceString=s1.replaceAll("c","*");
replaceString=s1.replaceAll("d","*");
replaceString=s1.replaceAll("e","*");
replaceString=s1.replaceAll("f","*");
replaceString=s1.replaceAll("g","*");
replaceString=s1.replaceAll("h","*");
replaceString=s1.replaceAll("i","*");
replaceString=s1.replaceAll("j","*");
replaceString=s1.replaceAll("k","*");
replaceString=s1.replaceAll("l","*");
replaceString=s1.replaceAll("m","*");
replaceString=s1.replaceAll("n","*");
replaceString=s1.replaceAll("o","*");
replaceString=s1.replaceAll("p","*");
replaceString=s1.replaceAll("q","*");
replaceString=s1.replaceAll("r","*");
replaceString=s1.replaceAll("s","*");
replaceString=s1.replaceAll("t","*");
replaceString=s1.replaceAll("u","*");
replaceString=s1.replaceAll("v","*");
replaceString=s1.replaceAll("w","*");
replaceString=s1.replaceAll("x","*");
replaceString=s1.replaceAll("y","*");
replaceString=s1.replaceAll("z","*");
replaceString=s1.replaceAll("A","*");
replaceString=s1.replaceAll("B","*");
replaceString=s1.replaceAll("C","*");
replaceString=s1.replaceAll("D","*");
replaceString=s1.replaceAll("E","*");
replaceString=s1.replaceAll("F","*");
replaceString=s1.replaceAll("G","*");
replaceString=s1.replaceAll("H","*");
replaceString=s1.replaceAll("I","*");
replaceString=s1.replaceAll("J","*");
replaceString=s1.replaceAll("K","*");
replaceString=s1.replaceAll("L","*");
replaceString=s1.replaceAll("M","*");
replaceString=s1.replaceAll("N","*");
replaceString=s1.replaceAll("O","*");
replaceString=s1.replaceAll("P","*");
replaceString=s1.replaceAll("Q","*");
replaceString=s1.replaceAll("R","*");
replaceString=s1.replaceAll("S","*");
replaceString=s1.replaceAll("T","*");
replaceString=s1.replaceAll("U","*");
replaceString=s1.replaceAll("V","*");
replaceString=s1.replaceAll("W","*");
replaceString=s1.replaceAll("X","*");
replaceString=s1.replaceAll("Y","*");
replaceString=s1.replaceAll("Z","*");
replaceString=s1.replaceAll("0","*");
replaceString=s1.replaceAll("1","*");
replaceString=s1.replaceAll("2","*");
replaceString=s1.replaceAll("3","*");
replaceString=s1.replaceAll("4","*");
replaceString=s1.replaceAll("5","*");
replaceString=s1.replaceAll("6","*");
replaceString=s1.replaceAll("7","*");
replaceString=s1.replaceAll("8","*");
replaceString=s1.replaceAll("9","*");
System.out.println(replaceString);
If s1 contains only the password, you'd want to mask all characters, and you'd end up with a string of the same length, consisting entirely of stars. This can be constructed directly:
replaceString = "*".repeat(s1.length());
Or, don't show anything about the password at all. Passwords are something that you want to give as little information as possible about, because information can make it (marginally or substantially) easier to guess/crack.
You can show something with a fixed number of stars; but I contend that's not showing anything useful, other than "this user has a password", which is presumably the same for all users.
Leave it out, use that space in the report for something else that provides information to the reader.
If you want to substitute your String with all asterisks, you can try as follow;
String s1="mypassword";
String replaceString="*";
replaceString = replaceString.repeat(s1.length());
String s1="mypassword";
String pass = s1.replaceAll("[\\W\\w]","*")
as per the code you can send the static value in the frontend or backend with ******* or in the worst case you can use replaceAll with regular expression to match all different passwords which are possible.
Security issues have been brought up already, so I'm just going to focus on the actual "task" here.
There's multiple ways to do this. One of them I would probably choose is this:
Instead of replacing them, as mentioned before, you can just create a new String that is the same length as your password string but fill it only with asterisks. This is pretty much what everybody has suggested already but I'm trying to keep it simple, as it seems like you're more on the beginner-side.
// We start off with an empty new String
String newString = "";
// Then we create a loop that adds a asterisk to the new String exactly, this is called x times where x is the length of the original passwordString
for (int i = 0; i < oldString.length; i++) { // This is a normal for-loop, if you don't know this concept yet, just google 'for-loop java'
newString = newString + "*"; // Here we set the newString to itself-i.e. the current content of the String plus an asterisk.
}
After this loop, we have a new String that has exactly as many characters as the old one but they're all asterisks. Now we could potentially replace the old String with the content of the new one, if that is what you want to do.
oldString = newString;
I want to be able to trim one quote from each side of a java string. Here are some examples.
"foo" -> foo
"foo\"" -> foo\"
"\"foo\"" -> \"foo\"
I'm currently using StringUtils.trim from common lang but when I end the string with a escaped quote, it trims that too because they are consecutive. I want to be able to trim exactly one quote.
I ended up using org.apache.commons.lang3.StringUtils.substringBetween and it works.
You may also use the substring() method and trim the first and last characters on condition although it's a bit long.
trimedString= s.substring((s.charAt(0)=='"')?1:0 , (s.charAt(s.length()-1)=='"')?s.length()-1:s.length());
I prefer to use this String method
public String[] split(String regex)
basically if you feed in the quotation mark then you will get an array of strings holding all of the chunks between your quotation marks.
String[] parts = originalString.split("\"");
String quoteReduced = parts[0];
for (int i = 1; i < (parts.length() -1); i++){
quoteReduced = quoteReduced.concat( parts[i] +"\"" );
}
quoteReduced = quoteReduced.concat( "\"" +parts[parts.length()-1]);
While it may not be the most straight forward it is the way that I would get around this. The first piece and last piece could be included in the loop but would require an if statement.
I wrote a code that does several string operations including checking whether a given string matches with a certain regular expression. It ran just fine with 70,000 input but it started to give me out of memory error when I iteratively ran it for five-fold cross validation. It just might be the case that I have to assign more memory, but I have a feeling that I might have written an inefficient code, so wanted to double check if I didn't make any obvious mistake.
static Pattern numberPattern = Pattern.compile("^[a-zA-Z]*([0-9]+).*");
public static boolean someMethod(String line) {
String[] tokens = line.split(" ");
for(int i=0; i<tokens.length; i++) {
tokens[i] = tokens[i].replace(",", "");
tokens[i] = tokens[i].replace(";", "");
if(numberPattern.matcher(tokens[i]).find()) return true;
}
return false;
}
and I have also many lines like below:
token.matches("[a-z]+[A-Z][a-z]+");
Which way is more memory efficient? Do they look efficient enough? Any advice is appreciated!
Edited:
Sorry, I had a wrong code, which I intended to modify before posting this question but I forgot at the last minute. But the problem was I had many similar looking operations all over, aside from the fact that the example code did not make sense, I wanted to know if regexp comparison part was efficient.
Thanks for all of your comments, I'll look through and modify the code following the advice!
Well, first at all, try a second look at your code... it will always return a "true" value ! You are not reading the 'match' variable, just putting values....
At second, String is immutable, so, each time you're splitting, you're creating another instances... why don't you try so create a pattern that makes the matches you want ignoring the commas and semicolons? I'm not sure, but I think it will take you less memory...
Yes, this code is inefficient indeed because you can return immediately once you've found that match = true; (no point to continue looping).
Further, are you sure you need to break the line into tokens ? why not check the regex only once ?
And last, if all comparisons checks failed, you should return false (last line).
Instead of altering the text and splitting it you can put it all in the regex.
// the \\b means it must be the start of the String or a word
static Pattern numberPattern = Pattern.compile("\\b[a-zA-Z,;]*[0-9,;]*[0-9]");
// return true if the string contains
// a number which might have letters in front
public static boolean someMethod(String line) {
return numberPattern.matcher(line).find());
}
Aside from what #alfasin has mentioned in his answer, you should avoid duplicating code; Rewrite the following:
{
tokens[i] = tokens[i].replace(",", "");
tokens[i] = tokens[i].replace(";", "");
}
Into:
tokens[i] = tokens[i].replaceAll(",|;", "");
And please just compute this before it was .split(), such that the operation doesn't have to be repeated within the loop:
String[] tokens = line.replaceAll(",|;", "").split(" ");
^^^^^^^^^^^^^^^^^^^^^^
Edit: After staring at your code for a bit I think I have a better solution, using regex ;)
public static boolean someMethod(String line) {
return Pattern.compile("\\b[a-zA-Z]*\\d")
.matcher(line.replaceAll(",|;", "")).find();
}
Online Regex DemoOnline Code Demo
\b is a Word Boundary.
It asserts position at the Boundary of a word (Start of line + after spacing)
Code Demo STDOUT:
foo does not match
bar does not match
bar1 does match
foo baz bar bar1 lolz does match
password_01 does not match
I want to match certain group of characters in a String independent of their order in the String using regex fucntion. However, the only requirement is that they all must be there.
I have tried
String elD = "15672";
String t = "12";
if ((elD.matches(".*[" + t + "].*"))) {
System.out.println(elD);
}
This one checks whether any of the characters are present. But I want all of them to be there.
Also I tried
String elD = "15672";
String t = "12";
if ((elD.matches(".*(" + t + ").*"))) {
System.out.println(elD);
}
This does not work as well. I have searched quite a while but I could not find an example when all of the characters from the pattern must be present in the String independent of their order.
Thanks
You can write regex for this but it would not look nice. If you would want to check if your string contains anywhere x and y you would need to use few times look-ahead like
^(?=.*x)(?=.*y).*$
and use it like
yourStirng.matches(regex);
But this way you would need to create your own method which would generate you dynamic regex and add (?=.*X) for each character you want to check. You would also need to make sure that this character is not special in regex like ? or +.
Simpler and not less effective solution would be creating your own method which would check if your string contains all searched characters, something like
public static boolean containsUnordered(String input, String searchFor){
char[] characters = searchFor.toCharArray();
for (char c: characters)
if (!input.contains(String.valueOf(c)))
return false;
return true;
}
You can built a pattern from the search string using the replaceAll method:
String s = "12";
String pattern = s.replaceAll("(.)", "(?=[^$1]*$1)");
Note: You can't test the same character several times. (i.e. 112 gives (?=[^1]*1)(?=[^1]*1)(?=[^2]*2) that is exactly the same as (?=[^1]*1)(?=[^2]*2))
But in my opinion Pshemo method is probably more efficient.
Okay, I'm a huge newbie in the world of java and I can't seem to get this program right. I am suppose to delete the duplicated characters in a 2 worded string and printing the non duplicated characters.
for example:I input the words "computer program." the output should be "cute" because these are the only char's that are not repeated.
I made it until here:
public static void main(String[] args) {
System.out.print("Input two words: ");
String str1 = Keyboard.readString();
String words[] = str1.split(" ");
String str2 = words[0] + " ";
String str3 = words[words.length - 1] ;
}
but i don't know how to output the characters. Could someone help me?
I don't know if I should use if, switch, for, do, or do-while...... I'm confused.
what you need is to build up logic for your problem. First break the problem statement and start finding solution for that. Here you go for steps,
Read every character from a string.
Add it to a collection, but before adding that, just check whether it exists.
If it exists just remove it and continue the reading of characteer.
Once you are done with reading the characters, just print the contents of collection to console using System.out.println.
I will recommend you to refer books like "Think like A Programmer". This will help you to get started with logic building.
Just a hint: use a hash map (http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html).
Adding following code after last line of your main program will resolve your issue.
char[] strChars = str2.toCharArray();
String newStr="";
for (char c : strChars) {
String charStr = ""+c;
if(!str3.contains(charStr.toLowerCase()) && !str3.contains(charStr.toUpperCase())){
newStr+=c;
}
}
System.out.println(newStr);
This code loops through all the characters of the first word and check if the second string contains that character (In any form of case Lower or Upper). If it is not containing, adding it to output string and at the end printing it.
Hope this will work in your case.
How about doing it in just 1 line?
str = str.replaceAll("(.)(?=.*\\1)", "");