Looking for a Regular Expression in Java to separate a String that represents complex numbers. A code sample would be great.
The input string will be in the form:
"a+bi"
Example: "300+400i", "4+2i", "5000+324i".
I need to retrieve 300 & 400 from the String.'
I know we can do it crudely in this way.
str.substring(0, str.indexOf('+'));
str.substring(str.indexOf('+')+1,str.indexOf("i"));
I need to retrieve 300 & 400 from the String.
What about using String.split(regex) function:
String s[] = "300-400i".split("[\\Q+-\\Ei]");
System.out.println(s[0]+" "+s[1]); //prints 300 400
Regex that matches this is: /[0-9]{1,}[+-][0-9]{1,}i/
You can use this method:
Pattern complexNumberPattern = Pattern.compile("[0-9]{1,}");
Matcher complexNumberMatcher = complexNumberPattern.matcher(myString);
and use find and group methods on complexNumberMatcher to retrieve numbers from myString
Use this one:
[0-9]{1,}
It'll return the numbers.
Hope it helps.
Regex
([-+]?\d+\.?\d*|[-+]?\d*\.?\d+)\s*\+\s*([-+]?\d+\.?\d*|[-+]?\d*\.?\d+)i
Example Regex
http://rubular.com/r/FfOAt1zk0v
Example Java
string regexPattern =
// Match any float, negative or positive, group it
#"([-+]?\d+\.?\d*|[-+]?\d*\.?\d+)" +
// ... possibly following that with whitespace
#"\s*" +
// ... followed by a plus
#"\+" +
// and possibly more whitespace:
#"\s*" +
// Match any other float, and save it
#"([-+]?\d+\.?\d*|[-+]?\d*\.?\d+)" +
// ... followed by 'i'
#"i";
Regex regex = new Regex(regexPattern);
Console.WriteLine("Regex used: " + regex);
while (true)
{
Console.WriteLine("Write a number: ");
string imgNumber = Console.ReadLine();
Match match = regex.Match(imgNumber);
double real = double.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture);
double img = double.Parse(match.Groups[2].Value, CultureInfo.InvariantCulture);
Console.WriteLine("RealPart={0};Imaginary part={1}", real, img);
}
Try this one. As for me, it works.
public static void main(String[] args) {
String[] attempts = new String[]{"300+400i", "4i+2", "5000-324i", "555", "2i", "+400", "-i"};
for (String s : attempts) {
System.out.println("Parsing\t" + s);
printComplex(s);
}
}
static void printComplex(String in) {
String[] parts = in.split("[+-]");
int re = 0, im = 0, pos = -1;
for (String s : parts) {
if (pos != -1) {
s = in.charAt(pos) + s;
} else {
pos = 0;
if ("".equals(s)) {
continue;
}
}
pos += s.length();
if (s.lastIndexOf('i') == -1) {
if (!"+".equals(s) && !"-".equals(s)) {
re += Integer.parseInt(s);
}
} else {
s = s.replace("i", "");
if ("+".equals(s)) {
im++;
} else if ("-".equals(s)) {
im--;
} else {
im += Integer.parseInt(s);
}
}
}
System.out.println("Re:\t" + re + "\nIm:\t" + im);
}
Output:
Parsing 300+400i
Re: 300
Im: 400
Parsing 4i+2
Re: 2
Im: 4
Parsing 5000-324i
Re: 5000
Im: -324
Parsing 555
Re: 555
Im: 0
Parsing 2i
Re: 0
Im: 2
In theory you could use something like this:
Pattern complexNumberPattern = Pattern.compile("(.*)+(.*)");
Matcher complexNumberMatcher = complexNumberPattern.matcher(myString);
if (complexNumberMatcher.matches()) {
String prePlus = complexNumberMatcher.group(1);
String postPlus = complexNumberMatcher.group(2);
}
The advantage this would give you over selecting the numbers, is that it would allow you to read things like:
5b+17c as 5b and 17c
edit: just noticed you didn't want the letters, so never mind, but this would give you more control over it in case other letters appear in it.
Related
I want to convert a string number starts with 00 to + such as 0046760963101 to +46760963101. Is there any solution to handle it via regex?
If not what solution do you recommend?
Addenda :
If it starts with 000 or more, I do not want to replace with + sign.
with regex assuming the input is a numeric string
s.replaceFirst("^00", "+")
or with regex if you aren't sure of the input format
s.replaceFirst("^00([0-9]+)$", "+$1")
or with a simple match
s.startsWith("00") ? "+"+s.substring(2) : s
Inculding the added requirement: If it starts with 000 or more, I do not want to replace with + sign.
String normalized = phone;
if ( !phone.matches("000+([0-9]+)") && phone.startsWith("00")) {
normalized = "+"+phone.substring(2);
}
Check you input in regex tester like: https://www.freeformatter.com/java-regex-tester.html#ad-output
You can try something like this
public static void main(String[] args) {
String number="0046760963101";
if(number.startsWith("00")) {
number=number.replaceFirst("00", "+");
}
System.out.println(number);
}
You could replace the 00 with a + like so:
String str = "0046760963101";
String newStr = "+";
for (int i = 2; i < str.length(); i++)
{
newStr += str.charAt(i);
}
Without regex:
String str = "0046760963101";
String replaced = str.charAt(2) == '0' ? str : str.substring(0, 2).replace("00", "+") + str.substring(2);
System.out.println(replaced);
will print:
+46760963101
I have a string that has multiple substring which has to be extracted. Strings which will be extracted is between ' character.
I could only extract the first or the last one when I use indexOf or regex.
How could I extract them and put them into array or list without parsing the same string only?
resultData = "Error 205: 'x' data is not crawled yet. Check 'y' and 'z' data and update dataset 't'";
I have a tried below;
protected static String errorsTPrinted(String errStr, int errCode) {
if (errCode== 202 ) {
ArrayList<String> ar = new ArrayList<String>();
Pattern p = Pattern.compile("'(.*?)'");
Matcher m = p.matcher(errStr);
String text;
for (int i = 0; i < errStr.length(); i++) {
m.find();
text = m.group(1);
ar.add(text);
}
return errStr = "Err 202: " + ar.get(0) + " ... " + ar.get(1) + " ..." + ar.get(2) + " ... " + ar.get(3);
}
Edit
I used #MinecraftShamrock 's approach.
if (errCode== 202 ) {
List<String> getQuotet = getQuotet(errStr, '\'');
return errStr = "Err 202: " + getQuotet.get(0) + " ... " + getQuotet.get(1) + " ..." + getQuotet.get(2) + " ... " + getQuotet.get(3);
}
You could use this very straightforward algorithm to do so and avoid regex (as one can't be 100% sure about its complexity):
public List<String> getQuotet(final String input, final char quote) {
final ArrayList<String> result = new ArrayList<>();
int n = -1;
for(int i = 0; i < input.length(); i++) {
if(input.charAt(i) == quote) {
if(n == -1) { //not currently inside quote -> start new quote
n = i + 1;
} else { //close current quote
result.add(input.substring(n, i));
n = -1;
}
}
}
return result;
}
This works with any desired quote-character and has a runtime complexity of O(n). If the string ends with an open quote, it will not be included. However, this can be added quite easily.
I think this is preferable over regex as you can ba absolutely sure about its complexity. Also, it works with a minimum of library classes. If you care about efficiency for big inputs, use this.
And last but not least, it does absolutely not care about what is between two quote characters so it works with any input string.
Simply use the pattern:
'([^']++)'
And a Matcher like so:
final Pattern pattern = Pattern.compile("'([^']++)'");
final Matcher matcher = pattern.matcher(resultData);
while (matcher.find()) {
System.out.println(matcher.group(1));
}
This loops through each match in the String and prints it.
Output:
x
y
z
t
Here is a simple approach (assuming there are no escaping characters etc.):
// Compile a pattern to find the wanted strings
Pattern p = Pattern.compile("'([^']+)'");
// Create a matcher for given input
Matcher m = p.matcher(resultData);
// A list to put the found strings into
List<String> list = new ArrayList<String>();
// Loop over all occurrences
while(m.find()) {
// Retrieve the matched text
String text = m.group(1);
// Do something with the text, e.g. add it to a List
list.add(text);
}
I'm trying to find a way to cycle through a string and get data within two characters, for example... I have the following String.
String test = "<172>Lorem Ipsum";
Lets say I want the data that is in-between the two characters '<' & '>'
So the result should be "172"
Now, if the string was going to be 3 digits inbetween these every time, using a sub-string would be fine, however that's not the case, as this string will be changing, so lets say this string could be
String test = "<9>Lorem Ipsum"
I would need the result to be "9"
How should I go about getting this information.
The code will be the following:
String test = "<172>Lorem Ipsum";
int index1 = test.indexOf('<');
int index2 = test.indexOf('>', index1);
String result = test.substring(index1 + 1, index2);
System.out.println("result = " + result);
And the result:
result = 172
String data = test.substring(test.indexOf("<")+1,test.indexOf(">"));
You can use regexp to get the data you need.
Something like this maybe
Pattern p = Pattern.compile("^<(\\d+)>");
Matcher m = p.matcher("<172>Lorem Ipsum");
if (m.find())
System.out.println(m.group(1));
else
System.out.println("your string doesn't start with \"<digits>\"");
In fact for this you can also try using replaceAll with a regex.
System.out.println("<172>Lorem Ipsum".replaceAll(".*<|>.*", ""));
Try something like this:
public Test() {
String test = "<172>Lorem Ipsum";
String number = "";
if (test.startsWith("<")) {
for (int index = 1 ; index < test.length() ; index++) {
if (!test.substring(index, index+1).equals(">")) {
number += test.substring(index, index+1);
} else {
break;
}
}
}
System.out.println(number);
}
int leftBound = data.indexOf("<");
int rightBound = data.indexOf(">");
data.substring(leftBound+1, rightBound));
Figured it out. It was one of those "Ask" then instantly figure it out things.
I need a regular expression to do the following:
I have this String: 123.45.678.7 and I need to replace all (.) characters from the second. The result will be 123.456787
¿Can anyone help me please?
System.out.println(
"123.45.678.7".replaceAll("\\G((?!^).*?|[^\\.]*\\..*?)\\.", "$1"));
123.456787
This can also be done without a regular expression:
String str = "123.45.678.7";
String[] arr = str.split("\\.", 2);
System.out.println(arr[0] + "." + arr[1].replace(".", ""));
123.456787
This code matches all of the periods with a regular expression, then puts the first decimal point back in the String.
Here are the test results:
123.45.678.7, 123.456787
And here's the code.
public class SecondMatch {
public String match(String s) {
StringBuilder builder = new StringBuilder();
String[] parts = s.split("\\.");
for (int i = 0; i < parts.length; i++) {
builder.append(parts[i]);
if (i == 0) {
builder.append(".");
}
}
return builder.toString();
}
public static void main(String[] args) {
String s = "123.45.678.7";
String t = new SecondMatch().match(s);
System.out.println(s + ", " + t);
}
}
Just create a function...
function removeAllButFirst(myParam)
{
var numReplaces = 0;
var retVal = myParam.replace(/\./g, function(allMatch, currMatch) {
return ++numReplaces==1 ? '.' : ''; });
return retVal;
}
Just had a rummage and found this on the net - its fairly crude, but would do the job...
retVal = retVal.replaceFirst(".","$");
retVal = retVal.replaceAll(".","");
retVal = retVal.replaceFirst("$",".");
This does assume you don't have any $'s in your input - if you do pick a different char.
Its not great and there is probably a better single regex on Java using something like LookBehinds but I'm not a Java dev so couldnt say.
This regex should also work:
String str = "123.45.678.9";
String repl = str.replaceAll("([^.]*\\.[^.]*|[^.]*)\\.", "$1");
// repl = 123.456789
I am working on some socket programming stuff and attempting to match some strings. The format is as follows:
1.) Some text
where the one represents any number, and some text refers to anything (including letters, numbers, quotation marks, etc).
I tried using [0-9]*\\.\\).* but it doesn't return a match. What am I doing wrong and how do I fix it?
Edit
As requested, here is my code:
/** Parses data returned by the server */
public void getSocketData(String data) {
String[] lines = data.split("\\r?\\n");
this.fileHosts = new String[lines.length];
Pattern p = Pattern.compile("[0-9]*\\.\\).*");
for (int i = 0; i < lines.length; i++) {
String line = lines[i];
if (p.matcher(line).matches()) {
//The format is: 1.) "b.jpg" from "192.168.1.101:40000"
String[] info = line.split("\"");
this.fileHosts[i] = info[3]; //this should now contain <addr:port>
System.out.println("Adding " + fileHosts[i] + " to fileHosts");
}
else {
System.out.println("No Match!");
}
}
}//getSocketData
This works for me:
public static void main(String args[]) {
String s = "1.) Some text";
System.out.println(s.replaceFirst("^[0-9]+\\.\\).*$","matched"));
}
Output:
matched
EDIT: Same result with the following:
String s = "1.) \"b.jpg\" from \"192.168.1.101:40000\"";
That is the example in the comment in your code
EDIT2: I try also your code:
String s = "1.) \"b.jpg\" from \"192.168.1.101:40000\"";
Pattern p = Pattern.compile("^[0-9]+\\.\\).*$"); // works also if you use * instead of +
if (p.matcher(s).matches()) {
System.out.println("match");
}
else {
System.out.println("No Match!");
}
The result is
match
Try using this regex: ^[0-9]+\\.\\).*$