In all other related posts people asked about removing leading or/and trailing spaces in String java. Now, my question is how to get the leading or trailing spaces? What I could think is for example to get the trailing spaces using such a function:
private String getTrailingSpaces(String str) {
return str.replace(str.replaceFirst("\\s+$", ""), "");
}
But I'm not sure if this is correct or even if it is, is there any better way to do this?
I'm not an expert but I think you should perform 2 distinct regexp, one for leading spaces and one for trailing spaces.
private static final Pattern LEADING = Pattern.compile("^\\s+");
private static final Pattern TRAILING = Pattern.compile("\\s+$");
public String getLeadingSpaces(String str) {
Matcher m = LEADING.matcher(str);
if(m.find()){
return m.group(0);
}
return "";
}
public String getTrailingSpaces(String str) {
Matcher m = TRAILING.matcher(str);
if(m.find()){
return m.group(0);
}
return "";
}
try this
String leading = str.replaceAll("^(\\s+).+", "$1");
String tailing = str.replaceAll(".+?(\\s+)$", "$1");
Try something like this:
private String getTrailingSpaces(String str) {
Pattern p = Pattern.compile(".*(\\s+)$");
Matcher m = p.matcher(str);
String trailing = "";
if (m.matches) {
trailing = m.group(1);
}
return trailing;
}
Try this.You would need ArrayUtils from Apache Commons though.
String str1 = " abc ";
char[] cs = str1.toCharArray();
Character[] characters = ArrayUtils.toObject(cs);
// System.out.println(characters.length); // 6
for (Character character : characters) {
if (character.isSpace(character.charValue())) {
// PROCESS ACCORDINGLY
} else {
// PROCESS ACCORDINGLY
}
}
Related
I have this alphabet: {'faa','fa','af'}
and I have this string: "faaf"
I have this regex: "(faa|fa|af)*" which helps me match the string with the alphabet.
How do I make Java trim my string into: {fa,af}, which is the correct way to write the string: "faaf" based on my alphabet?
here is my code:
String regex = "(faa|fa|af)*";
String str = "faaf";
boolean isMatch = Pattern.matches(regex, str);
if(isMatch)
{
//trim the string
while(str.length()!=0)
{
Pattern pattern = Pattern.compile("^(faa|fa|af)(faa|fa|af)*$");
Matcher mc = pattern.matcher(str);
if (mc.find())
{
String l =mc.group(1);
alphabet.add(l);
str = str.substring(l.length());
System.out.println("\n"+ l);
}
}
}
Thanks to Aaron who helped me with this problem.
You need a loop.
Pattern pattern = Pattern.compile(regex + "*");
LinkedList<String> parts = new LinkedList<>();
while (!str.isEmpty()) {
Matcher m = pattern.matcher(str);
if (!m.matches()) { // In the first loop step.
break;
}
parts.addFirst(m.group(1)); // The last repetition matching group.
str = str.substring(0, m.start(1));
}
String result = parts.stream().collect(Collectors.joining(", ", "{", "}"));
This utilizes that a match (X)+ will yield in m.group(1) the last occurrence's value of X.
Unfortunately the regex module does not provide a bored-open matches, such as the overloaded replaceAll with a lambda working on a single MatchResult.
Note that matches applies to the entire string.
I have a case where I need to extract the string within double quotes in one var and the rest of the string in another var.
Two possibilities:
String: "Franklin B" Benjamin
Result:
var1 = Franklin B
var2 = Benjamin
String: Benjamin "Franklin B"
Result:
var1 = Benjamin
var2 = Franklin B
Regex/Without regex; I am open to any method.
Give this a try...
Basically you remove any leading delimiter in the string before you perform the split. This way you don't have to worry about a leading empty element.
public static void main(String[] args) {
String testString = "\"Franklin B\" Benjamin";
String testString2 = "Benjamin \"Franklin B\"";
displaySplitResults(mySplit(testString, "\""));
displaySplitResults(mySplit(testString2, "\""));
}
private static String[] mySplit(final String input, final String delim)
{
return input.replaceFirst("^" + delim, "").split(delim);
}
private static void displaySplitResults(String[] splitResults) {
if (splitResults.length == 2) {
String var1 = splitResults[0].trim();
String var2 = splitResults[1].trim();
System.out.println(var1);
System.out.println(var2);
}
}
Results:
Franklin B
Benjamin
Benjamin
Franklin B
A simple non-regex way to do it:
public static String[] split(String input) {
if (input.charAt(0) == '"') {
return input.substring(1).split("\" ");
} else {
return input.substring(0, input.length() - 1).split(" \"");
}
}
First check whether the first character is ". Then remove the quote from either beginning or the end and simply split it.
The following will get you a List with the values you want:
private List<String> getValues(String input) {
List<String> matchList = new ArrayList<>();
Pattern regex = Pattern.compile("[^\\s\"']+|\"[^\"]*\"|'[^']*'");
Matcher regexMatcher = regex.matcher(input);
while (regexMatcher.find()) {
matchList.add(regexMatcher.group());
}
return matchList;
}
Taken from Regex for splitting a string using space when not surrounded by single or double quotes
#Shar1er80 Nice piece of work without regex. Worked great.
I also tried with regex:
//Using regex to get values separated by whitespace but keeping values with double quotes
RegexOptions options = RegexOptions.None;
Regex regex = new Regex( #"((""((?<token>.*?)(?<!\\)"")|(?<token>[\w]+))(\s)*)", options );
string input = #" Here is ""my string"" it has "" six matches"" ";
var result = (from Match m in regex.Matches( input )
where m.Groups[ "token" ].Success
select m.Groups[ "token" ].Value).ToList();
Gave me exact result.
For example, if I had (-> means return):
aBc123afa5 -> aBc
168dgFF9g -> 168
1GGGGG -> 1
How can I do this in Java? I assume it's something regex related but I'm not great with regex and so not too sure how to implement it (I could with some thought but I have a feeling it would be 5-10 lines long, and I think this could be done in a one-liner).
Thanks
String myString = "aBc123afa5";
String extracted = myString.replaceAll("^([A-Za-z]+|\\d+).*$", "$1");
View the regex demo and the live code demonstration!
To use Matcher.group() and reuse a Pattern for efficiency:
// Class
private static final Pattern pattern = Pattern.compile("^([A-Za-z]+|\\d+).*$");
// Your method
{
String myString = "aBc123afa5";
Matcher matcher = pattern.matcher(myString);
if(matcher.matches())
System.out.println(matcher.group(1));
}
Note: /^([A-Za-z]+|\d+).*$ and /^([A-Za-z]+|\d+)/ both works in similar efficiency. On regex101 you can compare the matcher debug logs to find out this.
Without using regex, you can do this:
String string = "168dgFF9g";
String chunk = "" + string.charAt(0);
boolean searchDigit = Character.isDigit(string.charAt(0));
for (int i = 1; i < string.length(); i++) {
boolean isDigit = Character.isDigit(string.charAt(i));
if (isDigit == searchDigit) {
chunk += string.charAt(i);
} else {
break;
}
}
System.out.println(chunk);
public static String prefix(String s) {
return s.replaceFirst("^(\\d+|\\pL+|).*$", "$1");
}
where
\\d = digit
\\pL = letter
postfix + = one or more
| = or
^ = begin of string
$ = end of string
$1 = first group `( ... )`
An empty alternative (last |) ensures that (...) is always matched, and always a replace happens. Otherwise the original string would be returned.
I have result, which is either a text or numeric value, such as:
String result;
result = "avsds";
result = "123";
result = "345.45";
Sometimes the results also contain commas like:
result = "abc,def";
result = "1,234";
I want to remove the commas from result only if it is a numeric value, and not if it is simple text.
What is the best way of going about this?
Here is your answer:
String regex = "(?<=[\\d])(,)(?=[\\d])";
Pattern p = Pattern.compile(regex);
String str = "Your input";
Matcher m = p.matcher(str);
str = m.replaceAll("");
System.out.println(str);
This only affects NUMBERS, not strings, as you asked.
Try adding that in your main method. Or try this one, it receives input:
String regex = "(?<=[\\d])(,)(?=[\\d])";
Pattern p = Pattern.compile(regex);
System.out.println("Value?: ");
Scanner scanIn = new Scanner(System.in);
String str = scanIn.next();
Matcher m = p.matcher(str);
str = m.replaceAll("");
System.out.println(str);
The easiest way is to use two regexes. The first to make sure it is numeric (something along the lines of [0-9.,]*), and the second to clean it (result.replaceAll("/,//"))
You could try to parse the string first with any of the numeric classes (Integer, Double etc) after removing the unwanted characters, if the parsing succeeds, then it is a numeric and you can remove the unwanted characters from the original string.
Here I have used BigInteger since I am not sure about the precision for your requirement.
public static String removeIfNumeric(final String s, final String toRemove) {
final String result;
if (isNumeric(s, toRemove)) {
result = s.replaceAll(toRemove, "");
} else {
result = s;
}
return result;
}
public static boolean isNumeric(final String s, final String toRemoveRegex) {
try {
new BigInteger(s.replaceAll(toRemoveRegex, ""));
return true;
} catch (NumberFormatException e) {
return false;
}
}
This question already has answers here:
Replace the last part of a string
(11 answers)
Closed 5 years ago.
Is there replaceLast() in Java? I saw there is replaceFirst().
EDIT: If there is not in the SDK, what would be a good implementation?
It could (of course) be done with regex:
public class Test {
public static String replaceLast(String text, String regex, String replacement) {
return text.replaceFirst("(?s)"+regex+"(?!.*?"+regex+")", replacement);
}
public static void main(String[] args) {
System.out.println(replaceLast("foo AB bar AB done", "AB", "--"));
}
}
although a bit cpu-cycle-hungry with the look-aheads, but that will only be an issue when working with very large strings (and many occurrences of the regex being searched for).
A short explanation (in case of the regex being AB):
(?s) # enable dot-all option
A # match the character 'A'
B # match the character 'B'
(?! # start negative look ahead
.*? # match any character and repeat it zero or more times, reluctantly
A # match the character 'A'
B # match the character 'B'
) # end negative look ahead
EDIT
Sorry to wake up an old post. But this is only for non-overlapping instances.
For example .replaceLast("aaabbb", "bb", "xx"); returns "aaaxxb", not "aaabxx"
True, that could be fixed as follows:
public class Test {
public static String replaceLast(String text, String regex, String replacement) {
return text.replaceFirst("(?s)(.*)" + regex, "$1" + replacement);
}
public static void main(String[] args) {
System.out.println(replaceLast("aaabbb", "bb", "xx"));
}
}
If you don't need regex, here's a substring alternative.
public static String replaceLast(String string, String toReplace, String replacement) {
int pos = string.lastIndexOf(toReplace);
if (pos > -1) {
return string.substring(0, pos)
+ replacement
+ string.substring(pos + toReplace.length());
} else {
return string;
}
}
Testcase:
public static void main(String[] args) throws Exception {
System.out.println(replaceLast("foobarfoobar", "foo", "bar")); // foobarbarbar
System.out.println(replaceLast("foobarbarbar", "foo", "bar")); // barbarbarbar
System.out.println(replaceLast("foobarfoobar", "faa", "bar")); // foobarfoobar
}
use replaceAll and add a dollar sign right after your pattern:
replaceAll("pattern$", replacement);
You can combine StringUtils.reverse() with String.replaceFirst()
See for yourself: String
Or is your question actually "How do I implement a replaceLast()?"
Let me attempt an implementation (this should behave pretty much like replaceFirst(), so it should support regexes and backreferences in the replacement String):
public static String replaceLast(String input, String regex, String replacement) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (!matcher.find()) {
return input;
}
int lastMatchStart=0;
do {
lastMatchStart=matcher.start();
} while (matcher.find());
matcher.find(lastMatchStart);
StringBuffer sb = new StringBuffer(input.length());
matcher.appendReplacement(sb, replacement);
matcher.appendTail(sb);
return sb.toString();
}
Use StringUtils from apache:
org.apache.commons.lang.StringUtils.chomp(value, ignoreChar);
No.
You could do reverse / replaceFirst / reverse, but it's a bit expensive.
If the inspected string is so that
myString.endsWith(substringToReplace) == true
you also can do
myString=myString.replaceFirst("(.*)"+myEnd+"$","$1"+replacement)
it is slow, but works:3
import org.apache.commons.lang.StringUtils;
public static String replaceLast(String str, String oldValue, String newValue) {
str = StringUtils.reverse(str);
str = str.replaceFirst(StringUtils.reverse(oldValue), StringUtils.reverse(newValue));
str = StringUtils.reverse(str);
return str;
}
split the haystack by your needle using a lookahead regex and replace the last element of the array, then join them back together :D
String haystack = "haystack haystack haystack";
String lookFor = "hay";
String replaceWith = "wood";
String[] matches = haystack.split("(?=" + lookFor + ")");
matches[matches.length - 1] = matches[matches.length - 1].replace(lookFor, replaceWith);
String brandNew = StringUtils.join(matches);
I also have encountered such a problem, but I use this method:
public static String replaceLast2(String text,String regex,String replacement){
int i = text.length();
int j = regex.length();
if(i<j){
return text;
}
while (i>j&&!(text.substring(i-j, i).equals(regex))) {
i--;
}
if(i<=j&&!(text.substring(i-j, i).equals(regex))){
return text;
}
StringBuilder sb = new StringBuilder();
sb.append(text.substring(0, i-j));
sb.append(replacement);
sb.append(text.substring(i));
return sb.toString();
}
It really works good. Just add your string where u want to replace string in s and in place of "he" place the sub string u want to replace and in place of "mt" place the sub string you want in your new string.
import java.util.Scanner;
public class FindSubStr
{
public static void main(String str[])
{
Scanner on=new Scanner(System.in);
String s=on.nextLine().toLowerCase();
String st1=s.substring(0, s.lastIndexOf("he"));
String st2=s.substring(s.lastIndexOf("he"));
String n=st2.replace("he","mt");
System.out.println(st1+n);
}
}