Split string by "],[" - regex

I know one back slash / can be used to escape some special characters like (, . and double back slash // can be used to escape special characters in a string directly.
I want to split:
"[[0,0,1,0,0],[0,0,0,0,0],[0,0,0,1,0],[1,1,0,1,1],[0,0,0,0,0]]"
by ],[ between each sub array.
What should I do if I want to get all the sub arrays by splitting them to be "[[0,0,1,0,0", "0,0,0,0,0","0,0,0,1,0","1,1,0,1,1", "0,0,0,0,0]]" first.
If you have better idea on how to convert them directly into sub arrays including numbers only like "0,0,1,0,0", "0,0,0,0,0","0,0,0,1,0","1,1,0,1,1", "0,0,0,0,0" that will be even better.

Since both [ and ] at special characters in regex you need to escape them.
you can try with below:
str.split("\\],\\[");
Test code:
String str="[[0,0,1,0,0],[0,0,0,0,0],[0,0,0,1,0],[1,1,0,1,1],[0,0,0,0,0]]";
String[] strs = str.split("\\],\\[");
for(String s:strs){
System.out.println(s);
}
Output result:
[[0,0,1,0,0
0,0,0,0,0
0,0,0,1,0
1,1,0,1,1
0,0,0,0,0]]
If you want to remove the duplicate [[ and ]],just add below codes before split:
str = str.substring(2);
str = str.substring(0, str.length()-2);
Updated answer,if you want to eliminate all the brackets in between and at both ends by regex,you write regex like \[?\[((\d,)+\d) then fetch the first group of each match record data, below is the code:
String str = "[[0,0,1,0,0],[0,0,0,0,0],[0,0,0,1,0],[1,1,0,1,1],[0,0,0,0,0]]";
String regex = "\\[?\\[((\\d,)+\\d)";
Pattern r = Pattern.compile(regex);
Matcher m = r.matcher(str);
while (m.find()) {
System.out.println(m.group(1));
}
The output is
0,0,1,0,0
0,0,0,0,0
0,0,0,1,0
1,1,0,1,1
0,0,0,0,0

Your input is valid JSON, so I suggest using a JSON parser.
The code would look like this:
import javax.json.*;
JsonReader jsonReader = Json.createReader(new StringReader("[[0,0,1,0,0],[0,0,0,0,0],[0,0,0,1,0],[1,1,0,1,1],[0,0,0,0,0]]"));
JsonArray array = jsonReader.readArray();
jsonReader.close();
System.out.println("Array #2: " + array.getJsonArray(1)); // should give [0,0,0,0,0]
System.out.println("Array #3, 4th value: " + array.getJsonArray(2).getInt(3)); // should give 1

If you want the String to convert into a 2d-Array, you can use below functions that takes the String and returns the 2d-Array of ints:
private static int[][] getMatrixFromString(String arrayStrinng) {
String arrayString = arrayStrinng.substring(1, arrayStrinng.length() - 1);
String[] splitMajor = arrayString.split("],");
int rowCount = splitMajor.length, colCount = 0;
int[][] matrix = new int[rowCount][];
for (int row = 0; row < splitMajor.length; row++) {
String[] splitMinor = splitMajor[row].split(",");
if (colCount == 0) {
colCount = splitMinor.length;
matrix = new int[rowCount][colCount];
}
for (int i = 0; i < colCount; i++) {
if (splitMinor[i].startsWith("["))
splitMinor[i] = splitMinor[i].substring(1);
if (splitMinor[i].endsWith("]"))
splitMinor[i] = splitMinor[i].substring(0, splitMinor[i].length() - 1);
matrix[row][i] = Integer.parseInt(splitMinor[i]);
}
}
return matrix;
}

Related

Check if an array of string contains a regex string

I need to find if a particular string is included in the string array. I have written the below code and it does the job but is there any groovier way to do this?
boolean isApplePresent = false
randomItemList = ['red apple', 'dog', 'cat']
for(i = 0; i < randomItemList.size(); i++) {
if(randomItemList[i] ==~ ".*apple.*") {
isApplePresent = true
break
}
}
println(isApplePresent) //returns true
As per #barmar's comment I tried using any and this too works.
isApplePresent = randomItemList.any{e-> e ==~ ".*apple.*"}

Trying to properly substring with String

Given the following function:
If I execute setColor("R:0,G:0,B:255,");
I'm expecting the red, grn, blu values to be:
0 0 255 except I'm getting 0 0 0
It's working fine for R:255,G:0,B:0, or R:0,G:255,B:0, though.
int setColor(String command) {
//Parse the incoming command string
//Example command R:123,G:100,B:50,
//RGB values should be between 0 to 255
int red = getColorValue(command, "R:", "G");
int grn = getColorValue(command, "G:", "B");
int blu = getColorValue(command, "B:", ",");
// Set the color of the entire Neopixel ring.
uint16_t i;
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(red, grn, blu));
}
strip.show();
return 1;
}
int getColorValue(String command, String first, String second) {
int rgbValue;
String val = command.substring(command.indexOf(first)+2, command.indexOf(second));
val.trim();
rgbValue = val.toInt();
return rgbValue;
}
Without knowing your String implementation, I can only make an educated guess.
What happens is that indexOf(second) doesn't give you what you think.
"R:0,G:0,B:255,"
^ ^- indexOf("B:")
|- indexOf(",")
It works for your other cases as none of the things they look for occur more than once in the string.
Looking at the SparkCore Docs we find the documentation for both indexOf and substring.
indexOf()
Locates a character or String within another String. By default, searches from the beginning of the String, but can also start from a given index, allowing for the locating of all instances of the character or String.
string.indexOf(val)
string.indexOf(val, from)
substring()
string.substring(from)
string.substring(from, to)
So now to fix your problem you can use the second variant of indexOf and pass that the index you found from your first search.
int getColorValue(String command, String first, String second) {
int rgbValue;
int beg = command.indexOf(first)+2;
int end = command.indexOf(second, beg);
String val = command.substring(beg, end);
val.trim();
rgbValue = val.toInt();
return rgbValue;
}
In this instance, I would split the string using a comma as the delimiter then parse each substring into a key-value pair. You could use a vector of value for the second part if you always have the sequence "R,G,B" in which case why have the "R:", "G:" or "B:" at all?
I can suppose that command.indexOf(second) will always find you the first comma, therefore for B the val becomes empty string.
Assuming that indexOf is something similar to .Net's, maybe try
int start = command.indexOf(first)+2;
int end = command.indexOf(second, start)
String val = command.substring(start+2, end);
Note the second argument for the second call to indexOf, I think it will make indexOf to look for matches after start. I also think you'd better pass a "," as a second for all calls, and add +1 or -1 to end to compensate for this passing "," instead of "G" and "B".
Or just use another limiter for B part, like R:0,G:0,B:0. (dot instead of comma).
I ended up just modifying my code:
int setColor(String command) {
int commaIndex = command.indexOf(',');
int secondCommaIndex = command.indexOf(',', commaIndex+1);
int lastCommaIndex = command.lastIndexOf(',');
String red = command.substring(0, commaIndex);
String grn = command.substring(commaIndex+1, secondCommaIndex);
String blu = command.substring(lastCommaIndex+1);
// Set the color of the entire Neopixel ring.
uint16_t i;
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(red.toInt(), grn.toInt(), blu.toInt()));
}
strip.show();
return 1;
}
I simply just do: 255,0,0 and it works a treat.

Replace number with repeated characters [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Say I have a string: 8, and I wanted to replace numbers [0-9] with a . that would repeat as many times as the number. What regex string would I use?
e.g.: input string
8
output
........
You can't do this using only regular expressions so you'll have to rely on a language or library feature which allows substitution of matched strings with the result of calling a function with the match as an argument.
In Ruby:
"8".gsub(/[0-9]/) { |x| '.' * x.to_i } # => "........"
"812".gsub(/[0-9]/) { |x| '.' * x.to_i } # => "..........."
"a1b2".gsub(/[0-9]/) { |x| '.' * x.to_i } # => "a.b.."
In JavaScript:
function replaceNumbersWithDots(str) {
return (''+str).replace(/[0-9]/g, function(m) {
var s='', num=parseInt(m, 10);
for (i=0; i<num; i++) { s+= '.'; }
return s;
});
}
replaceNumbersWithDots('8'); // => "........"
replaceNumbersWithDots('812'); // => ".........."
replaceNumbersWithDots('a1b2'); // => "a.b.."
In Java:
public static void main(String args[]) throws Exception {
System.out.println(replaceNumbersWithDots("8")); // => "........"
System.out.println(replaceNumbersWithDots("812")); // => "..........."
System.out.println(replaceNumbersWithDots("a1b2")); // => "a.b.."
}
public static String replaceNumbersWithDots(String s) {
Pattern pattern = Pattern.compile("[0-9]");
Matcher matcher = pattern.matcher(s);
StringBuffer buf = new StringBuffer();
while (matcher.find()) {
int x = Integer.parseInt(matcher.group());
matcher.appendReplacement(buf, stringOfDots(x));
}
return buf.toString();
}
public static String stringOfDots(int x) {
String s = "";
for (int i=0; i<x; i++) { s += "."; }
return s;
}
This can't be done with standard regular expressions alone. As #m.buettner points out, you can in certain languages specify a function that processes the replacement. For example, with Python
>>> import re
>>> s = '8'
>>> re.sub(r'\d', lambda m: '.'*int(m.group()), s)
'........'
But maybe you don't even need a regex? Since you're only looking for single-character matches (namely \d), you can perhaps do something like this:
Initialize some sort of string buffer to hold the resultant string
Loop over the characters of your input string
If the character is a digit, parse it as an integer and append that many .s to your buffer.
Otherwise, append the character itself to your buffer.
Here's an implementation of this in Java:
String s = "8";
StringBuilder sb = new StringBuilder();
for (char c : s.toCharArray()) {
if (Character.isDigit(c)) {
int n = c - '0';
for (int i = 0; i < n; i++)
sb.append('.');
} else {
sb.append(c);
}
}
System.out.println(sb);
........
AS you didn't provide a lang, i made an exemple of solving it in php
$tr = array();
foreach(range(0, 9) as $nr)
{
$tr[$nr] = str_repeat('.', $nr);
}
echo strtr("Hello 8", $tr);
// Gives: "Hello ........"

How to remove the final character

The following function will generate a string with '\x' in between,
string GetHexEncode(string hexstring){
string swap = "\\x";
string h = "\\x";
int si = hexstring.length();
for (int i=0; i<hexstring.length(); i++)
{
if (i%2==0){
swap+=hexstring.at(i);
}
else
{
swap+=hexstring.at(i)+h;
}
}
return swap;
}
On occasion, the program outputs the following:
\x45\x39\xD3\x5B\x4F\xEA\x6F\x3C\xBC\x1B\xA0\xF4\xE7\x41\xE5\x8
\x45\x39\xD3\x5B\x4F\xEA\x6F\x3C\xBC\x1B\xA0\xF4\xE7\x41\xE5\x
If this happens, is there any way that I can change the last part into this:
\x45\x39\xD3\x5B\x4F\xEA\x6F\x3C\xBC\x1B\xA0\xF4\xE7\x41\xE5
Start out with an empty swap and append h + digits instead of appending an \x at the end.
additionally you should pre-allocate enough space in swap before starting your result as you know the final length of your result before. This would save reallocations of the string.

Switch every pair of words in a string (“ab cd ef gh ijk” becomes “cd ab gh ef ijk”) in c/c++

Switch every pair of words in a string (“ab cd ef gh ijk” becomes “cd ab gh ef ijk”) in c++ without any library function.
int main(){
char s[]="h1 h2 h3 h4";//sample input
switch_pair(s);
std::cout<<s;
return 0;
}
char * switch_pair(char *s){
char * pos = s;
char * ptr = s;
int sp = 0;//counts number of space
while(*pos){
if(*pos==' ' && ++sp==2){ //if we hit a space and it is second space then we've a pair
revStr_iter(ptr,pos-1);//reverse the pair so 'h1 h2' -> '2h 1h'
sp=0;//set no. of space to zero to hunt new pairs
ptr=pos+1;//reset ptr to nxt word after the pair i.e. h3'
}
pos++;
}
if(sp==1) //tackle the case where input is 'h1 h2' as only 1 space is there
revStr_iter(ptr,pos-1);
revWord(s); //this will reverse each individual word....i hoped so :'(
return s;
}
char* revStr_iter(char* l,char * r){//trivial reverse string algo
char * p = l;
while(l<r){
char c = *l;
*l = *r;
*r = c;
l++;
r--;
}
return p;
}
char* revWord(char* s){//this is the villain....need to fix it...Grrrr
char* pos = s;
char* w1 = s;
while(*pos){
if(*pos==' '){//reverses each word before space
revStr_iter(w1,pos-1);
w1=pos+1;
}
pos++;
}
return s;
}
Input - h1 h2 h3 h4
expected - h2 h1 h4 h3
actual - h2 h1 h3 4h
can any noble geek soul help plz :(((
IMO, what you're working on so far looks/seems a lot more like C code than C++ code. I think I'd start from something like:
break the input into word objects
swap pairs of word objects
re-construct string of rearranged words
For that, I'd probably define a really minimal string class. Just about all it needs (for now) is the ability to create a string given a pointer to char and a length (or something on that order), and the ability to assign (or swap) strings.
I'd also define a tokenizer. I'm not sure if it should really be a function or a class, but for the moment, let's jut say "function". All it does is look at a string and find the beginning and end of a word, yielding something like a pointer to the beginning, and the length of the word.
Finally, you need/want an array to hold the words. For a first-step, you could just use a normal array, then later when/if you want to have the array automatically expand as needed, you can write a small class to handle it.
int Groups = 1; // Count 1 for the first group of letters
for ( int Loop1 = 0; Loop1 < strlen(String); Loop1++)
if (String[Loop1] == ' ') // Any extra groups are delimited by space
Groups += 1;
int* GroupPositions = new int[Groups]; // Stores the positions
for ( int Loop2 = 0, Position = 0; Loop2 < strlen(String); Loop2++)
{
if (String[Loop2] != ' ' && (String[Loop2-1] == ' ' || Loop2-1 < 0))
{
GroupPositions[Position] = Loop2; // Store position of the first letter
Position += 1; // Increment the next position of interest
}
}
If you can't use strlen, write a function that counts any letters until it encounters a null terminator '\0'.