How do you assign an unknown substring (a Hex number) from a specific line in a txt file to a variable?
I've written the code to identify the necessary line and I've been told to use Regular Expressions (regex).
I don't know how to do that. Can it be done without regex?
This is an extract from an example txt file. I'm looking to get (and then compare Value(2) and Value(3)) but I need the Hex numbers first.
Default(2) = 0x00
Value(2) = 0xE0A64F36
Desc(2) = calculated from application
Address(2) = 0x60
Page(2) = Sensor
Name(3) = ROM CRC32
Type(3) = u32
Default(3) = 0x00
Value(3) = 0xE0A64F36
Desc(3) = fix CRC from ROM
Split by = and parse the hexadecimal number.
String s = "Value(2) = 0xE0A64F36";
String hex = s.split("=")[1].trim();
long l = Long.parseLong(hex.substring(2), 16);
// l == 3768995638
if you don't want to use regular expressions, you have to parse the string by the HEX pattern by yourself, such as getting the value part of the line (string after "=") and checking whether this part is in HEX format (starting with 0x and following characters are in 0-F) or using Integer.parseInt(String s, int radix) to try to parse it (catch the exception)
Assuming you have the strings already extracted and they are stored in 2 variables,
String value2 = "Value(2) = 0xE0A64F36";
String value3 = "Value(3) = 0xE0A64F36";
You can use substring and indexOf to get the actual value:
value2 = value2.substring(value2.indexOf("0x"));
value3 = value3.substring(value3.indexOf("0x"));
if (value2.compareToIgnoreCase(value3) == 0) {
// Do something here
}
You can do the extraction like this:
Pattern p = Pattern.compile("Value\\([23]\\) = (0x([0-9A-F]{8}))");
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println(m.group(1));
System.out.println(Long.parseLong(m.group(2), 16));
}
Notice: if you want only to test if value(2) and value(3) are the same, you dont need to convert anything. You can only compare strings.
Related
I've seen questions on how to prefix zeros here in SO. But not the other way!
Can you guys suggest me how to remove the leading zeros in alphanumeric text? Are there any built-in APIs or do I need to write a method to trim the leading zeros?
Example:
01234 converts to 1234
0001234a converts to 1234a
001234-a converts to 1234-a
101234 remains as 101234
2509398 remains as 2509398
123z remains as 123z
000002829839 converts to 2829839
Regex is the best tool for the job; what it should be depends on the problem specification. The following removes leading zeroes, but leaves one if necessary (i.e. it wouldn't just turn "0" to a blank string).
s.replaceFirst("^0+(?!$)", "")
The ^ anchor will make sure that the 0+ being matched is at the beginning of the input. The (?!$) negative lookahead ensures that not the entire string will be matched.
Test harness:
String[] in = {
"01234", // "[1234]"
"0001234a", // "[1234a]"
"101234", // "[101234]"
"000002829839", // "[2829839]"
"0", // "[0]"
"0000000", // "[0]"
"0000009", // "[9]"
"000000z", // "[z]"
"000000.z", // "[.z]"
};
for (String s : in) {
System.out.println("[" + s.replaceFirst("^0+(?!$)", "") + "]");
}
See also
regular-expressions.info
repetitions, lookarounds, and anchors
String.replaceFirst(String regex)
You can use the StringUtils class from Apache Commons Lang like this:
StringUtils.stripStart(yourString,"0");
If you are using Kotlin This is the only code that you need:
yourString.trimStart('0')
How about the regex way:
String s = "001234-a";
s = s.replaceFirst ("^0*", "");
The ^ anchors to the start of the string (I'm assuming from context your strings are not multi-line here, otherwise you may need to look into \A for start of input rather than start of line). The 0* means zero or more 0 characters (you could use 0+ as well). The replaceFirst just replaces all those 0 characters at the start with nothing.
And if, like Vadzim, your definition of leading zeros doesn't include turning "0" (or "000" or similar strings) into an empty string (a rational enough expectation), simply put it back if necessary:
String s = "00000000";
s = s.replaceFirst ("^0*", "");
if (s.isEmpty()) s = "0";
A clear way without any need of regExp and any external libraries.
public static String trimLeadingZeros(String source) {
for (int i = 0; i < source.length(); ++i) {
char c = source.charAt(i);
if (c != '0') {
return source.substring(i);
}
}
return ""; // or return "0";
}
To go with thelost's Apache Commons answer: using guava-libraries (Google's general-purpose Java utility library which I would argue should now be on the classpath of any non-trivial Java project), this would use CharMatcher:
CharMatcher.is('0').trimLeadingFrom(inputString);
You could just do:
String s = Integer.valueOf("0001007").toString();
Use this:
String x = "00123".replaceAll("^0*", ""); // -> 123
Use Apache Commons StringUtils class:
StringUtils.strip(String str, String stripChars);
Using Regexp with groups:
Pattern pattern = Pattern.compile("(0*)(.*)");
String result = "";
Matcher matcher = pattern.matcher(content);
if (matcher.matches())
{
// first group contains 0, second group the remaining characters
// 000abcd - > 000, abcd
result = matcher.group(2);
}
return result;
Using regex as some of the answers suggest is a good way to do that. If you don't want to use regex then you can use this code:
String s = "00a0a121";
while(s.length()>0 && s.charAt(0)=='0')
{
s = s.substring(1);
}
If you (like me) need to remove all the leading zeros from each "word" in a string, you can modify #polygenelubricants' answer to the following:
String s = "003 d0g 00ss 00 0 00";
s.replaceAll("\\b0+(?!\\b)", "");
which results in:
3 d0g ss 0 0 0
I think that it is so easy to do that. You can just loop over the string from the start and removing zeros until you found a not zero char.
int lastLeadZeroIndex = 0;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c == '0') {
lastLeadZeroIndex = i;
} else {
break;
}
}
str = str.subString(lastLeadZeroIndex+1, str.length());
Without using Regex or substring() function on String which will be inefficient -
public static String removeZero(String str){
StringBuffer sb = new StringBuffer(str);
while (sb.length()>1 && sb.charAt(0) == '0')
sb.deleteCharAt(0);
return sb.toString(); // return in String
}
Using kotlin it is easy
value.trimStart('0')
You could replace "^0*(.*)" to "$1" with regex
String s="0000000000046457657772752256266542=56256010000085100000";
String removeString="";
for(int i =0;i<s.length();i++){
if(s.charAt(i)=='0')
removeString=removeString+"0";
else
break;
}
System.out.println("original string - "+s);
System.out.println("after removing 0's -"+s.replaceFirst(removeString,""));
If you don't want to use regex or external library.
You can do with "for":
String input="0000008008451"
String output = input.trim();
for( ;output.length() > 1 && output.charAt(0) == '0'; output = output.substring(1));
System.out.println(output);//8008451
I made some benchmark tests and found, that the fastest way (by far) is this solution:
private static String removeLeadingZeros(String s) {
try {
Integer intVal = Integer.parseInt(s);
s = intVal.toString();
} catch (Exception ex) {
// whatever
}
return s;
}
Especially regular expressions are very slow in a long iteration. (I needed to find out the fastest way for a batchjob.)
And what about just searching for the first non-zero character?
[1-9]\d+
This regex finds the first digit between 1 and 9 followed by any number of digits, so for "00012345" it returns "12345".
It can be easily adapted for alphanumeric strings.
I have a String containing ASCII representation of a character i.e.
String test = "0x07";
Is there a way I can somehow parse it to its character value.
I want something like
char c = 0x07;
But what the character exactly is, will be known only by reading the value in the string.
You have to add one step:
String test = "0x07";
int decimal = Integer.decode(test);
char c = (char) decimal;
I'm trying to parse a html tag so far I got the text which can be as follows:
"Guide Price £50,000"
or
"£50,000"
or even
"£50,000 - £55,000"
In the third case to make things simpler all I need is the first price listed.
My question is how can I convert the following numbers into an int or double, preferably an int as the numbers are quite large. Would number formatter do this or would I need a regex expression especially if some text trails the tag block.
Example after what I got so far
String priceNumber = url.select("span.price").text(); //using JSoup Libary
String priceNumber = priceNumber.replaceAll("[^\\d.])
This removes everything which is not a digit I think.
What if the example has 2 numbers in it how do I get the first?
Use a regex with Matcher.find to search for occurrences, then remove the commas and try to parse. Here's the decimal case:
String input = "£50,000 - £55,000";
Pattern regex = Pattern.compile("\\d[\\d,\\.]+");
Matcher finder = regex.matcher(input);
if( finder.find() ) { // or while() if you want to process each
try {
double value = Double.parseDouble(finder.group(0).replaceAll(",", ""));
// do something with value
} catch (NumberFormatException e ) {
// handle unparseable
}
}
Youu can convert any String to a int or double with Integer.parseInt(\\String you want to convert) or Double.parseDouble(\\String you want to convert) respectively.
In your first and second case this would get you 50000.
In the third cae you need to split the string into 2 first and then repeat the trick.
Your title is a bit misleading as you are not asking on how to convert from pound to lets say euro.
Use a regex to remove the unimportant characters and then parse the result as a double. You can then truncate to int if you only care about dollar values.
NumberFormat format = NumberFormat.getInstance();
format.parse(priceNumber.replaceAll("[^\\d]*([\\d,]*).*", "$1")).doubleValue()
The first part of the replace pattern [^\\d] matches and throws away leading characters, the second part ([\\d,]) saves the next series of digits and commas, then the third part .* throws away the rest of the input.
Then the whole input is replaced with the contents of the first saved match (the second part of the replace pattern).
Then you use the NumberFormat class to parse the number (you could use Double.parseDouble() if it weren't for the comma)
This will work I think!
String string = "This is £50,000 pounds, this is £5.00 pounds.";
String newString = string;
while (string.contains("£")) {
if (string.indexOf("£") != -1) {
// it contains £
string = string.substring(string.indexOf("£"));
newString = string.substring(0, string.indexOf(" "));
string = string.replaceFirst(newString, "");
newString = newString.replaceAll("£", "");
newString = newString.replaceAll(",", "");
double money = Double.parseDouble(newString);
System.out.println(money);
}
}
you can try this out (for all the cases),
String priceNumber = "£500001 wcjnwknv122333- £55,000";
String regex = "£(\\d+,?\\d+)\\D?";
Pattern p =Pattern.compile(regex);
Matcher m = p.matcher(priceNumber);
if(m.find()){
System.out.println(m.group(1));
}
Try below regex :
((\$|£)\d+\s|(\$|£)\d+-(\$|£)\d+\s)
I want to format int numbers as hex strings. System.out.println(Integer.toHexString(1)); prints 1 but I want it as 0x00000001. How do I do that?
Try this
System.out.println(String.format("0x%08X", 1));
You can use the String.format to format an integer as a hex string.
System.out.println(String.format("0x%08X", 1));
That is, pad with zeros, and make the total width 8. The 1 is converted to hex for you. The above line gives: 0x00000001 and
System.out.println(String.format("0x%08X", 234));
gives: 0x000000EA
From formatting syntax documented on Java's Formatter class:
Integer intObject = Integer.valueOf(1);
String s = String.format("0x%08x", intObject);
System.out.println(s);
Less verbose:
System.out.printf("0x%08x", 1); //"Use %0X for upper case letters
I don't know Java too intimately, but there must be a way you can pad the output from the toHexString function with a '0' to a length of 8. If "0x" will always be at the beginning, just tack on that string to the beginning.
Java 17+
There is a new immutable class dedicated to conversion into and formatting hexadecimal numbers. The easiest way to go is using HexFormat::toHexDigits which includes leading zeroes:
String hex = "0x" + HexFormat.of().toHexDigits(1);
// 0x00000001
Beware, one has to concatenate with the "0x" prefix as such method ignores defined prefixes and suffixes, so the following snippet doesn't work as expected (only HexFormat::formatHex methods work with them):
String hex = HexFormat.of().withPrefix("0x").toHexDigits(1);
// 00000001
Returns the eight hexadecimal characters for the int value. Each nibble (4 bits) from most significant to least significant of the value is formatted as if by toLowHexDigit(nibble). The delimiter, prefix and suffix are not used.
Alternatively use the advantage of HexFormat::formatHex formatting to two hexadecimal characters, and a StringBuilder as an Appendable prefix containing "0x":
Each byte value is formatted as the prefix, two hexadecimal characters selected from uppercase or lowercase digits, and the suffix.
StringBuilder hex = HexFormat.of()
.formatHex(new StringBuilder("0x"), new byte[] {0, 0, 0, 1});
// 0x00000001
StringBuilder hex = HexFormat.of()
.formatHex(new StringBuilder("0x"), ByteBuffer.allocate(4).putInt(1).array());
// 0x00000001
You can use a java.util.Formatter or the printf method on a PrintStream.
This is String extension for Kotlin
//if lengthOfResultTextNeeded = 3 and input String is "AC", the result is = "0AC"
//if lengthOfResultTextNeeded = 4 and input String is "AC", the result is = "00AC"
fun String.unSignedHex(lengthOfResultTextNeeded: Int): String {
val count =
lengthOfResultTextNeeded - this.length
val buildHex4DigitString = StringBuilder()
var i = 1
while (i <= count) {
buildHex4DigitString.append("0")
++i
}
return buildHex4DigitString.toString() + this
}
Does anyone out there know of a regex command that will take the following string
url = http://184.154.145.114:8013/wlraac name = wlr samplerate = 44100 channels = 2 format = S16le
and remove everything but the following
wlr
This line will come up multiple times, where everything changes after the = sign and each time all I want to keep is whats after name =
any help is appreciated
You could do something like
.*name =\s*(\w+).*
and replace with the content of group 1
See it here on Regexr
I search for "name =" and anything before. The \s* matches the following whitespace.
Then the \w+ inside brackets. \w will match any character and digit and underscore (if you use the option Pattern.UNICODE_CHARACTER_CLASS otherwise it sticks to ASCII only) . Because of the brackets it is stored in the first group.
String in = " url = http://184.154.145.114:8013/wlraac name = wlr samplerate = 44100 channels = 2 format = S16le";
Pattern r = Pattern.compile(".*name =\\s*(\\w+).*");
Matcher m = r.matcher(in);
String result = m.replaceAll("$1");
System.out.println(result);
Or your code
String str = line2.replaceAll(".*name =\\S*(\\W).*", "$1");
From your description its a little bit hard to understand what you need.
But regex is overkill. You should use smth like:
String s = myString.substring(myString.indexOf("name =")+6);
I'd recommend you to extract the word that appears after =, i.e.
Pattern p = Pattern.compile("=\\s*(\\S+)");
Matcher m = p.matcher(str);
if (m.find()) {
String value = m.group(1); // contains your wlr
...............
}