I have a string that starts with 7 characters (let's say XXXXXXX) and after that there are 8 characters that represnet a decimal number.
For example: XXXXXXX30.00000 would be 30.00 (I want 2 decimal places)
So it should start on index 7 read until dot (.) + 2 decimal places. It should be a string, not a number. I tried with string.substring() but got stuck here.
First you can remove the first 7 characters by
var newString = yourString.removeRange(0,6)
then you can cast to a double if you're certain it will always be a number
var yourNumber = newString.ToDouble()
If you're not sure you can wrap in a try/catch eg:
try{
var yourNumber = newString.ToDouble()
}catch(e:TypeCastException){
println("Failed to cast to double - "+ e.message)
}
additionally, to round to a 2 decimal places:
val number2digits:Double = String.format("%.2f", yourNumber).toDouble()
I suggest you do it using the regex, [A-Za-z]{8}(\d+.\d{2})
Explanation of the regex:
[A-Za-z]{8} specifies 8 characters. If you want to support characters other than English alphabets, you can replace [A-Za-z] with \p{L} which specifies unicode letters.
(\d+.\d{2}) specifies a capturing group consisting of digits followed by . which in turn should be followed by 2 digits as per your requirement. A regex pattern can have more than one capturing groups. Since it is the first capturing group in this pattern, it can be accessed by group(1).
A test code:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
// Some test strings
String[] arr = { "abcdefgh30.00000", "abcdefgh300.0000", "abcdefgh3000.00", "abcdefgh3.00000",
"abcdefgh0.05000" };
Pattern pattern = Pattern.compile("[A-Za-z]{8}(\\d+.\\d{2})");
for (String s : arr) {
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
String str = matcher.group(1);
System.out.println(str);
}
}
}
}
Output:
30.00
300.00
3000.00
3.00
0.05
Related
I want to split a string of emojis into each emoji. so how can I do this in dart language?
void main() {
print('GoodJob'.split("")); // output: [G, o, o, d, J, o, b]
print('π€π±π'.split("")); // output: [οΏ½, οΏ½, οΏ½, οΏ½, οΏ½, οΏ½] but expected: ['π€','π±','π']
}
Docs from TextField recommends to use characters package to work with emoji in dart.
Docs describe as follows,
It's important to always use characters when dealing with user input text that may contain complex characters. This will ensure that extended grapheme clusters and surrogate pairs are treated as single characters, as they appear to the user.
For example, when finding the length of some user input, use string.characters.length. Do NOT use string.length or even string.runes.length. For the complex character "π¨βπ©βπ¦", this appears to the user as a single character, and string.characters.length intuitively returns 1. On the other hand, string.length returns 8, and string.runes.length returns 5!
import 'package:characters/characters.dart';
void main() {
print('π€π±π'.characters.split("".characters));
}
outputs
(π€, π±, π)
You can match all the emojis using regex, and then add them to a list:
List<String> splitEmoji(String text) {
final List<String> out = [];
final pattern = RegExp(
r'(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])');
final matches = pattern.allMatches(text);
for (final match in matches) {
out.add(match.group(0)!);
}
return out;
}
Regex credit
Usage:
print(splitEmoji('π€π±π')); // Output: [π€, π±, π]
You can use the runes property of String.
void main() {
final String emojis = 'π€π±π';
final Runes codePoints = emojis.runes;
for (final codePoint in codePoints) {
print(String.fromCharCode(codePoint));
}
}
I am looking for a way to get a String between 2 Strings using Arduino. This is the source String:
Hello, my name is John Doe# and my favourite number is 32#.
The output has to be:
String name = "John Doe"; //Between "name is " and "#"
String favouriteNumber = "32"; //Between "number is " and "#"
How can this be achieved with Arduino?
I am not able to find any information online about this. Those examples for C are not working anyway. I understand that using String is not recommended in Arduino, but I have to do it this way to make things simpler.
By the way, this method of using a '#' to indicate the end of the data is not an ideal way to do it as I would like the input to be more human readable and more natural. Would anyone please suggest another way to do this as well?
Thanks in advance!
Function midString find the substring that is between two other strings "start" and "finish". If such a string does not exist, it returns "". A test code is included too.
void setup() {
test();
}
void loop() {
delay(100);
}
String midString(String str, String start, String finish){
int locStart = str.indexOf(start);
if (locStart==-1) return "";
locStart += start.length();
int locFinish = str.indexOf(finish, locStart);
if (locFinish==-1) return "";
return str.substring(locStart, locFinish);
}
void test(){
Serial.begin(115200);
String str = "Get a substring of a String. The starting index is inclusive (the corresponding character is included in the substring), but the optional ending index is exclusive";
Serial.print(">");
Serial.print( midString( str, "substring", "String" ) );
Serial.println("<");
Serial.print(">");
Serial.print( midString( str, "substring", "." ) );
Serial.println("<");
Serial.print(">");
Serial.print( midString( str, "corresponding", "inclusive" ) );
Serial.println("<");
Serial.print(">");
Serial.print( midString( str, "object", "inclusive" ) );
Serial.println("<");
}
just searched for this and saw no answer so i cooked one up.
i prefer working with String as well because of code readability and simplicity.
for me its more important than squeezing every last drop of juice out of my arduino.
String name = GetStringBetweenStrings("Hello, my name is John Doe# and my favourite number is 32#." ,"name is ","#");
String GetStringBetweenStrings(String input, String firstdel, String enddel){
int posfrom = input.indexOf(firstdel) + firstdel.length();
int posto = input.indexOf(enddel);
return input.substring(posfrom, posto);
}
watch out for the first case its fine, but for the second one you would have to change the second filter sting to "#." so it doesn't use the first occurrence of the #
I need to remove last char in string in my case it's comma (","):
foreach(line; fcontent.splitLines)
{
string row = line.split.map!(a=>format("'%s', ", a)).join;
writeln(row.chop.chop);
}
I have found only one way - to call chop two times. First remove \r\n and second remove last char.
Is there any better ways?
import std.array;
if (!row.empty)
row.popBack();
As it usually happens with string processing, it depends on how much Unicode do you care about.
If you only work with ASCII it is very simple:
import std.encoding;
// no "nice" ASCII literals, D really encourages Unicode
auto str1 = cast(AsciiString) "abcde";
str1 = str1[0 .. $-1]; // get slice of everything but last byte
auto str2 = cast(AsciiString) "abcde\n\r";
str2 = str2[0 .. $-3]; // same principle
In "last char" actually means unicode code point (http://unicode.org/glossary/#code_point) it gets a bit more complicated. Easy way is to just rely on D automatic decoding and algorithms:
import std.range, std.stdio;
auto range = "ΠΊΠΈΡΠΈΠ»Π»ΠΈΡΠ°".retro.drop(1).retro();
writeln(range);
Here retro (http://dlang.org/phobos/std_range.html#.retro) is a lazy reverse iteration function. It takes any range (unicode string is a valid range) and returns wrapper that is capable of iterating it backwards.
drop (http://dlang.org/phobos/std_range.html#.drop) simply pops a single range element and ignores it. Calling retro again will reverse the iteration order back to normal, but now with the last element dropped.
Reason why it is different from ASCII version is because of nature of Unicode (specifically UTF-8 which D defaults to) - it does not allow random access to any code point. You actually need to decode them all one by one to get to any desired index. Fortunately, D takes care of all decoding for you hiding it behind convenient range interface.
For those who want even more Unicode correctness, it should be possible to operate on graphemes (http://unicode.org/glossary/#grapheme):
import std.range, std.uni, std.stdio;
auto range = "abcde".byGrapheme.retro.drop(1).retro();
writeln(range);
Sadly, looks like this specific pattern is not curently supported because of bug in Phobos. I have created an issue about it : https://issues.dlang.org/show_bug.cgi?id=14394
NOTE: Updated my answer to be a bit cleaner and removed the lambda function in 'map!' as it was a little ugly.
import std.algorithm, std.stdio;
import std.string;
void main(){
string fcontent = "I am a test\nFile\nwith some,\nCommas here and\nthere,\n";
auto data = fcontent
.splitLines
.map!(a => a.replaceLast(","))
.join("\n");
writefln("%s", data);
}
auto replaceLast(string line, string toReplace){
auto o = line.lastIndexOf(toReplace);
return o >= 0 ? line[0..o] : line;
}
module main;
import std.stdio : writeln;
import std.string : lineSplitter, join;
import std.algorithm : map, splitter, each;
enum fcontent = "some text\r\nnext line\r\n";
void main()
{
fcontent.lineSplitter.map!(a=>a.splitter(' ')
.map!(b=>"'" ~ b ~ "'")
.join(", "))
.each!writeln;
}
Take a look, I use this extension method to replace any last character or sub-string, for example:
string testStr = "Happy holiday!";<br>
Console.Write(testStr.ReplaceVeryLast("holiday!", "Easter!"));
public static class StringExtensions
{
public static string ReplaceVeryLast(this string sStr, string sSearch, string sReplace = "")
{
int pos = 0;
sStr = sStr.Trim();
do
{
pos = sStr.LastIndexOf(sSearch, StringComparison.CurrentCultureIgnoreCase);
if (pos >= 0 && pos + sSearch.Length == sStr.Length)
sStr = sStr.Substring(0, pos) + sReplace;
} while (pos == (sStr.Length - sSearch.Length + 1));
return sStr;
}
}
I need to input a String that is basically a membership number.
It has to contain two letters in the beginning followed by four numbers.
For example, AA1111 or AB1234.
How can I validate that the first two digits are letters and the last four digits are integers?
In c#:
public void validate()
{
string input = textBox1.Text;
var re = "^[a-zA-Z]{2}[0-9]{4}$";
if (Regex.IsMatch(input, re))
{
MessageBox.Show("true");
}
else
{
MessageBox.Show("false");
}
}
In javaScripts:
function validate()
{
var input = document.getElementById("Text1").value;
var re = new RegExp(/^[a-zA-Z]{2}[0-9]{4}$/);
if (re.test(input))
{
alert("true");
}
else
{
alert("false");
}
}
If we split regular expression, it validates input string in start and end
^[a-zA-Z]{2}-----------------------------------------[0-9]{4}$
First two character must be alphabets
^ =*from start*
[a-zA-Z] =*lower and upper case alpha*
{2} =*Exactly two character*
Last four characters must be digits
[0-9] =*digits*
{4} =*exactly four charater*
$ =*at end*
I want to limit the no. of character that can be put on JTextField because on my database I have this column that has Sex,Status (which the no. of char. allowed is 1 only).
and Middle Initial (which the no. of char. allowed is 2 only).
This what I have in my mind :
(for Sex,Status column)
String text = jTextField2.getText();
int count = text.();
if (count>1) {
(delete the next character that will be input)
}
(for M.I. column)
String text = jTextField1.getText();
int count = text.();
if (count>2) {
(delete the next character that will be input)
}
is this possible? is there a command that will delete the next character, so the no. of char. is acceptable for my database?
Sure. Just use String#substring.
String middleInitial = "JKL";
middleInitial.substring(0, 2);
System.out.println(middleInitial); // => JK
Similarly, you can use substring(0, 1) for sex.
It might be better if sex is an enum, though.
public enum Sex {
MALE("m"), FEMALE("f");
final String symbol;
private Sex(String symbol) {
this.symbol = symbol;
}
}
Now you can use it like this:
String sex = "male";
Sex.valueOf(sex.toUpperCase());
Or directly
Sex.MALE;
Instead of a text field for sex, you might use a JComboBox so the user can only choose one of the two options. This way you're sure to have valid input.