Replace Special characters with Character references in string using java - java

I have a String with special characters which I want to be replaced by corresponding reference.
For example
InputString -> Hi <Nishanth> How &are you !
OutputString -> Hi &ltNishanth&gt How &ampare you &excl
I tried using concept of replace. But I couldn't achieve the desired result ..
I want a function which would do it for me in Java.

replaceAll should be able to do the job just fine.
First, let's make a quick tuple class to represent a pair of Strings: the string to search for and the string to replace that with:
private static class StringTuple{
private String k;
private String v;
public StringTuple(String one, String two){
k = one;
v = two;
}
}
With that, we can build a list of special characters to search for and their corresponding replacements. Note that this list is going to be used in the order that we create it, so it's important that we replace special characters that might show up in other replacements first (such as & or ;).
ArrayList<StringTuple> specialChars = new ArrayList<>();
specialChars.add(new StringTuple("&", "&"));
specialChars.add(new StringTuple("<", "<"));
specialChars.add(new StringTuple(">", ">"));
Finally, we can write a function that loops over the list of special chars and replaces all occurrences with the replacement string:
public static String replaceSpecialChars(String s, ArrayList<StringTuple> specialChars){
for(StringTuple e: specialChars){
s = s.replaceAll(e.k, e.v);
}
return s;
}
Here's a runnable main based off of the above code:
public static void main(String[] args) {
ArrayList<StringTuple> specialChars = new ArrayList<>();
specialChars.add(new StringTuple("&", "&"));
specialChars.add(new StringTuple("<", "<"));
specialChars.add(new StringTuple(">", ">"));
System.out.println(replaceSpecialChars("Hi <Nishanth> How are &you !", specialChars));
}
Output: Hi <Nishanth> How are &you !

Related

Given string want to filter out certain part of string into an arraylist

I have string:
String s = #Jay125,150012 90,#Jay222,150043 00,
I want to filter out value after jay(125,222) and add that to separate ArrayList.
I want to filter out 150012, 151243 together add that to separate ArrayList.
I want to filter out 90,00 together add that to separate ArrayList.
I tried by doing this but it doesn't quite do what I want
Pattern reg = Pattern.compile(",");
ArrayList<String> jay = reg.splitAsStream(s))
.filter(role -> role.contains("Jay"))
.map(String::trim)
.collect(Collectors.toCollection(ArrayList::new));
If I have understood correctly your case, you're having a String whose pattern is in the form #Jay<Number>,<Number> <Number> and then it keeps repeating itself. Also, you would like to have every bit of this pattern (jay bit, first number bit and second number bit) stored in three separate lists.
As suggested in the comments, you could achieve this with a regex using capturing groups to identify the three portions and retrieve them at every match.
#(Jay\d+),(\d+) (\d+)
Here is a link to test the regex:
https://regex101.com/r/ULtDTu/1
Here is a code snippet with the implementation:
public class Main {
public static void main(String[] args) {
String s = "#Jay125,150012 90,#Jay222,150043 00,";
Pattern pattern = Pattern.compile("#(Jay\\d+),(\\d+) (\\d+)");
Matcher matcher = pattern.matcher(s);
List<String> listJay = new ArrayList<>();
List<String> listFirstSubNum = new ArrayList<>();
List<String> listSecSubNum = new ArrayList<>();
while (matcher.find()) {
listJay.add(matcher.group(1));
listFirstSubNum.add(matcher.group(2));
listSecSubNum.add(matcher.group(3));
}
System.out.println(listJay);
System.out.println(listFirstSubNum);
System.out.println(listSecSubNum);
}
}
You can also test the code here:
https://ideone.com/0hwpyl

String data manipulation with Maps for very large data input

I have solved Two Strings problem in HackerRank
Here is the problem.
Given two strings, determine if they share a common substring. A
substring may be as small as one character.
For example, the words "a", "and", "art" share the common substring.
The words "be" and "cat" do not share a substring.
Function Description
Complete the function twoStrings in the editor below. It should return
a string, either YES or NO based on whether the strings share a common
substring.
twoStrings has the following parameter(s):
s1, s2: two strings to analyze .
Output Format
For each pair of strings, return YES or NO.
However, when extra-long strings are subjected, my code does not run within the time limit. Any suggestions to improve efficiency? I think I can improve substring finding with using the Stream API. But I'm not sure how to use it in this context. Could someone please help me to understand this better?
public static void main(String[] args) {
String s1 = "hi";
String s2 = "world";
checkSubStrings(s1, s2);
}
static void checkSubStrings(String s1, String s2) {
Map<String, Long> s1Map = new HashMap<>();
Map<String, Long> s2Map = new HashMap<>();
findAllSubStrings(s1, s1Map);
findAllSubStrings(s2, s2Map);
boolean isContain = s2Map.entrySet().stream().anyMatch(i -> s1Map.containsKey(i.getKey()) );
if (isContain) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
static void findAllSubStrings(String s, Map<String, Long> map) {
for (int i = 0; i < s.length(); i++) {
String subString = s.substring(i);
for (int j = subString.length(); j > 0; j--) {
String subSubString = subString.substring(0, j);
if (map.containsKey(subSubString)) {
map.put(subSubString, map.get(subSubString) + 1);
} else {
if (!subSubString.equals(""))
map.put(subSubString, 1L);
}
}
}
}
Update
I just solved the question using HashSets.
I optimized the code using Set. Now it runs with very large Strings.
static String twoStrings(String s1, String s2) {
String result = null;
Set<Character> s1Set = new HashSet<>();
Set<Character> s2Set = new HashSet<>();
for(char a : s1.toCharArray()){
s1Set.add(a);
}
for(char a : s2.toCharArray()){
s2Set.add(a);
}
boolean isContain = s2Set.stream().anyMatch(s1Set::contains);
if(isContain){
result = "YES";
} else {
result = "NO";
}
return result;
}
If 2 strings share an N (>=2) character substring, they also share an N-1 character substring (because you can chop a character off the end of the common substring, and this will still be found in both strings). Extending this argument, they also share a 1-character substring.
As such, all you need to check are single-character substrings.
Fill your maps with single-character substrings instead, and you will avoid creating (and checking) unnecessary substrings. (And just use a Set instead of a Map, you never use the counts).
// Yields a `Set<Integer>`, which can be used directly to check.
return s.codePoints().boxed().collect(Collectors.toSet());

replace or remove special char from List<String> java

replace or remove special char from List java
List<String> somestring = ['%french',
'#spanish',
'!latin'];
How to remove the special characters and replace it with space.
List<String> somestring = ['%french',
'#spanish',
'!latin'];
somestring.replaceall('%','');
How to get this as result
List<String> somestring = ['french',
'spanish',
'latin'];
First, never use a raw List. You have a List<String>. Second, a String literal (in Java) is surrounded by double quotes (") not single quotes. Third, you can stream your List<String> and map the elements with a regular expression and collect them back to the original List<String>. Like,
List<String> somestring = Arrays.asList("%french", "#spanish", "!latin");
somestring = somestring.stream().map(s -> s.replaceAll("\\W", ""))
.collect(Collectors.toList());
System.out.println(somestring);
Outputs (as requested)
[french, spanish, latin]
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches {
private static String REGEX = "\\!|\\%|\\#"; //control on Special characters...
private static String INPUT = "The %dog% says !meow. " + "!All #dogs #say meow.";
private static String REPLACE = ""; //Replacement string
public static void main(String[] args) {
Pattern p = Pattern.compile(REGEX);
//get a matcher object
Matcher m = p.matcher(INPUT);
INPUT = m.replaceAll(REPLACE);
System.out.println(INPUT);
}
}
Added a sample snippet to explain the same, please extend to collections accordingly.

How to list all words matching criteria from String sentence in Java

Imagine having following 'sentence' as String object:
String sentence = "AsomethingB 123 AsomethingElseB AsomethingBC abc A0B 987 ...";
How can I list everything to a String[] of words which begins with String A and ends with String B, like:
String[] words = new String[] {"AsomethingB", "AsomethingElseB", "A0B"};
// note the AsomethingBC is not here.
More globally I am looking for method which will do following:
public String[] listWords(String sentence, String startSequence, String endSequence) {
// sentence will represent String from which "extract" words
// startSequence will represent "A" from example, may contain more characters
// endSequence will represent "B" from example, may contain more characters
// return type String[] will return all matches (AsomethingB...) from example
}
Is something like this possible ?
Here's one solution:
return Pattern.compile(" ")
.splitAsStream(sentence)
.filter(w -> w.startsWith(startSequence))
.filter(w -> w.endsWith(endSequence))
.toArray(String[]::new);
You can use java 8's streams to get the result, e.g.:
public static String[] listWords(String sentence, String startSequence, String endSequence) {
return Arrays.stream(sentence.split("\\s+"))
.filter(s -> s.startsWith(startSequence))
.filter(s -> s.endsWith(endSequence))
.collect(Collectors.toList()).toArray(new String[0]);
}
This method splits the spring based on space and performs the comparison. You can call this method like this:
public static void main(String[] args) {
System.out.println(Arrays.asList(listWords("AsomethingB 123 AsomethingElseB AsomethingBC abc A0B 987", "A", "B")));
}
You can also use toLowerCase() method if you want case insensitive matching.
Update
If you words are not split by whitespace and you want to split on capital letters then you can use the following (assuming the string will contain numbers as well):
System.out.println(Arrays.asList("AsomethingB123AsomethingElseBAsomethingBCabcA0B987".split("(?=[A-Z])(?<=[A-Z])|(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)")));
This would show the tokens that are applied to the stream.
Also, on a second thought, it'll be better to add one more parameter (regex) to listWords method so that it's not tied to any specific pattern, e.g.:
public static String[] listWords(String sentence, String regex, String startSequence, String endSequence) {
return Arrays.stream(sentence.split(regex))
.filter(s -> s.startsWith(startSequence))
.filter(s -> s.endsWith(endSequence))
.collect(Collectors.toList()).toArray(new String[0]);
}
It can be called like this:
System.out.println(Arrays.asList(listWords("AsomethingB123AsomethingElseBAsomethingBCabcA0B987", "(?=[A-Z])(?<=[A-Z])|(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)", "A", "B")));
You could leverage the Java's .split command. So it could like like:
String sentence = "My Sentence AbbC";
String[] splitted = sentence.split(" ");
and then from there you can loop over the splitted array to find if your index has the desired result. Furthermore, you can also try .split("A*B") which would result in splitted containing strings that start and end with A and B respectively as being in their own singular index, while everything else would be as one long string in an index.
ex:
S: AbbD
S: Hello World, Acc
Here's a non-streams approach:
public static List<String> listWords(String sentence, String startSequence, String endSequence) {
List<String> lst = new ArrayList<>();
for (String s : sentence.split(" "))
if (s.startsWith(startSequence) && s.endsWith(endSequence))
lst.add(s);
return lst;
}
Done it as a List<String> because they're less faff than arrays. You can always convert it afterwards if you really need an array.

Word to Symbol converter [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I want to make a system that when written a letter (example:a) it converts it to a symbols (example:ԅ).
How do I really do it? I know it seems simple, but I am very, very new into programming, all I can do is a simple calendar or a calculator.
I've tried to do it alone, but got nowhere. I type a whole word but it just prints the first letter instead of the word, that contains 4+. For example I type "aura" but it prints only "ԅ"
THANKS A LOT TO ALL OF YOU!!! I FINALLY MADE IT!!!!
Use string = string.replace("a", "ԅ");
where string is the given word (in your case, aura).
You can use a HashMap<Character, Character> in this case!
If you don't know what that is, it's basically a "dictionary". You can just make the HashMap like this in your case:
a -> ԅ
b -> !
c -> #
d -> #
Note: The above is not real code, just a visual representation! And I don't know what your symbols mean and how to type them, so I used normal symbols
See? It's really a dictionary. When you look for "a", you get "ԅ", when you look for "b", you get "!", etc. Do you get it now?
Okay, now let's see the code
HashMap<Character, Character> characterMap = new HashMap<> (); //Create a new HashMap
characterMap.put ('a', 'ԅ'); // Put an entry in the "dictionary"
characterMap.put ('b', '!');
//and so on... I am lazy
Now suppose you are able to get the user input and stored it in a string called input. Just like Anthony's code, you do this:
for (Map.Entry<Character, Character> entry : map.entrySet()) {
input = input.replace(entry.getKey(), entry.getValue());
}
This is basically saying that,
Go to find every entry in the dictionary.
For each entry,
Store it in the "entry" variable
Replace all the occurrences of entry's key by entry's value
Hi #EpicJavaNoob and welcome on StackOverflow.
You could solve your problem by using a Map and replace() function on Strings.
You have to create this class in your program.
public class MyReplacer {
private static final Map<Character, Character> map = new HashMap<Character, Character>();
static { // the static block is used to instantiate the Map once for all
map.put('a' , '\u2026');
map.put('b', '+');
}
public static String encode(String stringToEncode) {
// for each entry in the hashmap, we replace the character by his corresponding key
for (Map.Entry<Character, Character> entry : map.entrySet()) {
stringToEncode = stringToEncode.replace(entry.getKey(), entry.getValue());
}
return stringToEncode;
}
}
Then in your code you can use the previous class this way :
public static void main(String[] args) {
String str = "aura";
String encodedStr = MyReplacer.encode(str);
}
A Map is use to associate a key to a value.
I do agree that this is not the simple solution you can find, but this is how you'l learn coding, looking at code wrote by other and try to understand how it works, and why it has ben wrote this way.
I'd use a for loop that reads the string supplied one letter at a time then makes a new string that "translates" every individual letter.
Here's some quick code:
Scanner i = new Scanner(System.in);
System.out.print("Enter string:");
String start = i.next();
int len = start.length;
String end = "";
for (int a = 0, a<len, a++) {
if (start.Charat(a) == "a") {
end = end.append(ԅ)
} etc...
}
I just made this off the top of my head, I'll try to make a working version if you give me more substitutions :)
The best way is to code a Translator class with a translation table:
Edit: I've chosen the Map alternative instead of the char[] one (my first thought), after agreeing with AnthonyRaymond's suggest.
public class Translator
{
private Map<Character,Character> table=createTable();
public String translate(String input)
{...}
}
To construct the table, you must set just the explicit mappings (in order to reduce the table to the minimum size):
private Map<Character,Character> createTable()
{
Map<Character,Character> table=new HashMap<Character,Character>();
// Set the explicit mappings:
table.put('a', 'ԅ');
table.put('b', ...);
return table;
}
The translation rutine must first index the table, and if the character is not found, select the input character (in order to leave untranslated the blanks, newlines and rest of non-translatable characters):
public String translate(String input)
{
StringBuilder stb=new StringBuilder(input.length());
for (int i=0;i<input.length();i++)
{
char inputChar=input.charAt(i);
Character outputChar=table.get(inputChar);
if (outputChar==null)
{
outputChar=inputChar;
}
stb.append(outputChar);
}
return stb.toString();
}

Categories