I have the following code, trying to match pyramids of increasing * count, surrounded by an equivalent number of spaces on either side.
//pyramid
var p = " * \n" +
" *** \n" +
" ***** \n" +
" ******* \n" +
" ********* \n" +
"***********\n";
//not a pyramid - rows 2 and 3 do not increase in width
var np = " * \n" +
" ***** \n" +
" ***** \n" +
" ******* \n" +
" ********* \n" +
"***********\n";
//pyramid with more width variation, non-point top
var pspace = " ** \n" +
" **** \n" +
" ********** \n" +
" ************** \n" +
" **************** \n" +
"**********************\n";
final var REGEX = "((?<S>\\s*)(?<star>\\**)\\k<S>\\R(?=$|((?<S2>\\s*)(?<extra>\\*+)\\k<star>\\k<extra>\\k<S2>\\R)))+";
System.out.println("p is a pyramid: "+Pattern.matches(REGEX, p));
System.out.println("np is a pyramid: "+Pattern.matches(REGEX, np));
System.out.println("pspace is a pyramid: "+Pattern.matches(REGEX, pspace));
Output:
p is a pyramid: true
np is a pyramid: false
pspace is a pyramid: true
The final thing I want to do is make sure that all "lines" of the input string are of equal length. At this point, I got completely stuck, as I couldn't really find anything but fixed-length String bounds (i.e. X{min, max}). So, here's what I'm wondering:
How can I make sure that all the lines within my string are pyramids (increasing number of stars from first line to last line (done), separated by new lines (done), centered within the spaces (done), and equal length lines (???))?
How can I simplify my regex to reduce the overuse of named capturing groups?
Regular expressions are incapable of doing the type of counting you are trying to accomplish, so you have to use a mixed strategy. Break up the string on newline boundaries then use a regular expression to match the leading and trailing spaces and the asterisks between them. But you will then have to see if the lengths of these matches meet your requirements by seeing how long these strings are using the length method that String objects possess:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class test
{
public static void main(String[] args) {
String p = " * \n" +
" *** \n" +
" ***** \n" +
" ******* \n" +
" ********* \n" +
"***********\n";
String[] lines = p.split("\n");
Pattern pattern = Pattern.compile("^(\\s*)(\\*+)(\\s*)$");
int lastLength = 0;
boolean isPyramid = true;
for (String line : lines) {
Matcher m = pattern.matcher(line);
m.find();
String spaces1 = m.group(1);
String spaces2 = m.group(3);
String asterisks = m.group(2);
int len = asterisks.length();
if (len <= lastLength || spaces1.length() != spaces2.length()) {
isPyramid = false;
break;
}
else {
lastLength = len;
}
}
System.out.println("p is a pyramid: " + isPyramid);
}
}
Related
I am writing this little section for a program I'm gonna write for initials of a name in java, and I need to determine the position of each space in it to be able to choose the initials. I'm testing it to make sure the spaces are been seen in the right position in the line, but for some reason, the position always comes wrong! Please help me.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("please enter full name:");
String name = in.nextLine();
int space = name.indexOf(" ");
int space1 = name.indexOf(" ", space) + space+1;
int space2 = name.indexOf(" ", space1) + space1+1;
int space3 = name.indexOf(" ", space2) + space2+1;
int space4 = name.indexOf(" ", space3) + space3+1;
int space5 = name.indexOf(" ", space4) + space4+1;
System.out.println(space + " " + space1 + " " + space2 + " " + space3 + " " + space4);
}
}
My idea using this line was to count up to each part of the line space that shows up after the last one and add 1 because java starts counting at 0.
(" ", space1) + space1+1;
Basically, if the name is "Jeff Luiz Jeff Luiz" the first space is at 4 and the next one is at 9, so it would the 4, then proceed to count after this space, starting at 0, which would find 4 again(because Luiz has the same amount of letters), sum up with the last space number to keep track of the real position(then it would be 8), and finally sum up with 1 because of how java works, and so on. When I ran these 4 words I found the result 4 9 19 19 19. Does anyone know what is the problem with my code?
Replace
int space1 = name.indexOf(" ", space) + space+1;
with
int space1 = name.indexOf(" ", space + 1);
because String#indexOf(String str, int fromIndex) returns the index within this string of the first occurrence of the specified substring, starting at the specified index.
Demo:
public class Main {
public static void main(String[] args) {
String name = "Arvind Kumar Avinash";
int space = name.indexOf(" ");
int space1 = name.indexOf(" ", space + 1);
System.out.println(space + ", " + space1);
}
}
Output:
6, 12
I want to delete empty line and rest of the character from my string, I would like to parse particular value alone from the string.
I want this value alone 23243232 from my string, after product price I've have empty line space and again I've some character so I'm using that empty line as delimiter and trying to get product price alone. But I'm getting other values also along with 23243232. Can someone help me to get only 23243232 from this string
String actualResponse = "--sGEFoZV85Qnkco_QAU5b6B3Tt1OrOOFkArwzoF_yDmmW5DfupJDtuHlh20LL2SAbWZb8a3exzoF_yDmmW5DfupJDtuHlh20LL2SAbWZb8a3exsGEFoZV85Qnkco_QAU5b6B3Tt1OrOOFkArw\r\n"
+ "Product-Discription: form-name; productName=\"iPhone\"\r\n" + "Product-Type: Mobile\r\n"
+ "Product-Price: 23243232\r\n" + "\r\n" + "%dsafdfw32.323efaeed\r\n" + "#$#####";
String productPrice = actualResponse.substring(actualResponse.lastIndexOf("Product-Price:") + 15);
System.out.println("Printing product price ..." + productPrice);
String finalString = productPrice.replaceAll(" .*", "");
This is the output I'm getting:
Printing product price ...23243232
%dsafdfw32.323efaeed
#$#####
But I want only 23243232 - this value alone.
Apply Regular Expression for more flexibility.
String content = "--sGEFoZV85Qnkco_QAU5b6B3Tt1OrOOFkArwzoF_yDmmW5DfupJDtuHlh20LL2SAbWZb8a3exzoF_yDmmW5DfupJDtuHlh20LL2SAbWZb8a3exsGEFoZV85Qnkco_QAU5b6B3Tt1OrOOFkArw\r\n"
+ "Product-Discription: form-name; productName=\"iPhone\"\r\n" + "Product-Type: Mobile\r\n"
+ "Product-Price: 23243232\r\n" + "\r\n" + "%dsafdfw32.323efaeed\r\n" + "#$#####";
String re1 = "\\bProduct-Price:\\s"; // Word 1
String re2 = "(\\d+)"; // Integer Number 1
Pattern p = Pattern.compile(re1 + re2, Pattern.DOTALL);
Matcher m = p.matcher(content);
while (m.find()) {
for (int i = 0; i <= m.groupCount(); i++) {
System.out.println(String.format("Group=%d | Value=%s",i, m.group(i)));
}
}
It will print out:
Group=0 | Value=Product-Price: 23243232
Group=1 | Value=23243232
first solution came in my mind. its not the best but will solve your problem.
StringBuilder finalString =new StringBuilder();
for (Character c : productPrice.toCharArray()) {
if(Character.isDigit(c)){
finalString.append(c);
}else{
break;
}
}
This is because you are printing the entire sub-string right from index: actualResponse.lastIndexOf("Product-Price:") + 15 to the end of the string.
You need to provide the end index too as a second parameter in substring method.
You need to use this:
int start = actualResponse.lastIndexOf("Product-Price:") + 15;
int end = actualResponse.indexOf("\r\n", start); // The first "\r\n" from the index `start`
String productPrice = actualResponse.substring(start, end);
This will give your final ans...
String actualResponse ="--sGEFoZV85Qnkco_QAU5b6B3Tt1OrOOFkArwzoF_yDmmW5DfupJDtuHlh20LL2SAbWZb8a3exzoF_y DmmW5DfupJDtuHlh20LL2SAbWZb8a3exsGEFoZV85Qnkco_QAU5b6B3Tt1OrOOFkArw\r\n"
+ "Product-Discription: form-name; productName=\"iPhone\"\r\n" + "Product-Type: Mobile\r\n"
+ "Product-Price: 23243232\r\n" + "\r\n" + "%dsafdfw32.323efaeed\r\n" + "#$#####";
String productPrice = actualResponse.substring(actualResponse.lastIndexOf("Product-Price:") + 15);
System.out.println("Printing content lenght..." + productPrice.split("\r\n")[0]);
Can someone tell me what I am doing wrong here? I'm trying to display the position of asterisks but i keep getting 1 in return.
package proj2;
import java.util.Scanner;
/**
* <p> Title: Project 2: String Manipulation </p>
* <p> Description: Ask the user to enter a URL and it will display
* the protocol, domain name and file name specified. </p>
* #author Mario Mendoza
*
*/
public class Project2 {
/**
*
* #param args arguments
*/
public static void main(String[] args ) {
Scanner s = new Scanner(System.in );
String sentence;
String word1;
String word2;
String word3;
String word4;
String asterisks1 = "*";
String asterisks2 = "*";
String asterisks3 = "*";
int firstWord;
int secondWord;
int thirdWord;
int fouthWord;
int wordLength1;
int wordLength2;
int wordLength3;
int wordLength4;
int positionOfAsterisks1;
int positionOfAsterisks2;
int positionOfAsterisks3;
char firstLetter;
int total;
word1 = s.next();
word2 = s.next();
word3 = s.next();
word4 = s.next();
System.out.println("You typed " + word1 + asterisks1 + word2 + asterisks2 + word3 + asterisks3 + word4);
sentence = new String(word1 + asterisks1 + word2 + asterisks2 + word3 + asterisks3 + word4);
wordLength1 = word1.length();
System.out.println(word1 + " has length " + wordLength1);
wordLength2 = word2.length();
System.out.println(word2 + " has length " + wordLength2);
wordLength3 = word3.length();
System.out.println(word3 + " has length " + wordLength3);
wordLength4 = word4.length();
System.out.println(word4 + " has length " + wordLength4);
positionOfAsterisks1 = sentence.indexOf(asterisks1);
positionOfAsterisks2 = sentence.indexOf(asterisks2);
positionOfAsterisks3 = sentence.indexOf(asterisks3);
System.out.println("The asterisks were found at position " + positionOfAsterisks1 + ", " + positionOfAsterisks2 + ", and " + positionOfAsterisks3);
}
}
Have your program perform the following tasks:
Prompt the user to enter a String containing exactly four words, separated only
by asterisks. The input string should not have any spaces. An example of the kind
of input this program will receive is I*love*computer*science. Display the
user’s input (as a confirmation to the user that the program understood the input).
Store each of the four words separately.
Display each word with its length. For example:
I has length 1.
love has length 4.
computer has length 8.
science has length 7.
Display the position of the asterisks in the original string. For example:
The asterisks were found at positions 1, 6, and 15.
Display the last letter of the first word.
Display the total aggregate length of the four words.
In addition, be sure to include a JavaDoc comment at the top of the file, that include’s the
program’s title, description, and author’s name.
4 Sample Run
You typed I*love*computer*science.
I has length 1.
love has length 4.
computer has length 8.
science has length 7.
The asterisks were found at positions 1, 6, and 15.
The last letter of the first word is I.
The total aggregate length of the four words is 20 letters.
public static void main(String[] args ) {
Scanner s = new Scanner(System.in );
String sentence;
String word1;
String word2;
String word3;
String word4;
word1 = s.next();
word2 = s.next();
word3 = s.next();
word4 = s.next();
System.out.println("You typed " + word1 + "*" + word2 + "*" + word3 + "*" + word4);
sentence = new String(word1 + "*" + word2 + "*" + word3 + "*" + word4);
System.out.println(word1 + " has length " + word1.length());
System.out.println(word2 + " has length " + word2.length());
System.out.println(word3 + " has length " + word3.length());
System.out.println(word4 + " has length " + word4.length());
System.out.print("The asterisks were found at position ");
// get the position of * and store the position index
int i = 0;
String positionOfAsterisks = "";
while (i < sentence.length()){
if (sentence.charAt(i) == '*')
positionOfAsterisks += i + ", ";
i++;
}
// remove the last comma and empty space then add in full stop
positionOfAsterisks = positionOfAsterisks.substring(0, positionOfAsterisks.length()-2);
positionOfAsterisks += "." ;
System.out.print(positionOfAsterisks);
}
Instead of using indexOf, I use a loop to iterate through your 'sentence'. Also, I removed the declaration of useless variables.
IndexOf will return just the index it found from the first index (if it's not stated in the 2nd arg of the method). And IndexOf method return the first position as 1 instead of 0.
The problem is that you are always searching in the given string for the same value, which is *. It doesn't matter what you name the variable, you are essentially running this line 3 times:
positionOfAsterisks1 = sentence.indexOf('*'); using 3 different variables, but each time it will always return 1. This is because each time it starts over, hits the first asterisk, and returns true.
What you need to do is make use of the second argument, which is the position to start from.
positionOfAsterisks1 = sentence.indexOf(asterisks1);
int temp = positionOfAsterisks1 + 1;
positionOfAsterisks2 = sentence.indexOf(asterisks1,temp);
temp = positionOfAsterisks2 + 1;
positionOfAsterisks3 = sentence.indexOf(asterisks1,temp);
What this does
The first line returns a value of 1. The next line sets temp to 2. Now the search starts from the third position (since array indices start at 0), and will thus not include the first asterisk. It will then hit the 7th character which is * and return 6. Again temp is set to 7, and again the search starts from the 8th character, and goes on till it hits the asterisk again at 15.
Note
You do not need to use 3 separate variables to hold the same *, it is only a waste of space. I would recommend using the same variable and eliminating the other two!
String fullWord;
String firstWord;
String secondWord;
String thirdWord;
String fourthWord;
int firstPositionOfAsterisk;
int secondPositionOfAsterisk;
int thirdPositionOfAsterisk;
int fullWordCharacters;
int firstWordCharacters;
int secondWordCharacters;
int thirdWordCharacters;
int fourthWordCharacters;
char lastLetterFirstWord;
// I will prompt the user to enter four words seperated by a *
fullWord = JOptionPane.showInputDialog("Please enter four words: ");
// I will use the position of the * to make things easier
firstPositionOfAsterisk = fullWord.indexOf("*");
firstWord = fullWord.substring(0, firstPositionOfAsterisk);
secondPositionOfAsterisk = firstWord.indexOf("*");
secondWord = fullWord.substring(firstPositionOfAsterisk + 1, secondPositionOfAsterisk);
thirdPositionOfAsterisk = secondWord.indexOf("*");
thirdWord = fullWord.substring(secondPositionOfAsterisk + 1, thirdPositionOfAsterisk);
fourthWord = fullWord.substring(thirdPositionOfAsterisk + 1);
firstWordCharacters = firstWord.length();
System.out.println(firstWord +" has a length of " + firstWordCharacters + " characters" );
secondWordCharacters = secondWord.length();
System.out.println(secondWord +" has length of " + secondWordCharacters + " characters" );
thirdWordCharacters = thirdWord.length();
System.out.println(thirdWord +" has length of " + thirdWordCharacters + " characters" );
fourthWordCharacters = fourthWord.length();
System.out.println(fourthWord +" has length of " + fourthWordCharacters + " characters" );
lastLetterFirstWord = firstWord.charAt(firstPositionOfAsterisk - 1);
System.out.println("The last letter of " + firstWord + "is " + lastLetterFirstWord);
fullWord = firstWord + secondWord + thirdWord + fourthWord;
fullWordCharacters = fullWord.length();
System.out.println(firstWord +", " + secondWord + ", " + thirdWord + ", " + fourthWord + "has length of" + fullWordCharacters);
I'm trying to get the user to enter 4 words seperated by an "*" for example She*will*call*back and I want an output like like this
She has length 3
will has length 4
call has length 4
back has length 4
The * symbols were found at positions: 3, 8, and 13
The last character of she is s
The length of She, will, call, and back is 15
But I keep getting this java.lang.StringIndexOutOfBoundsException error. How do I fix this?
This line crashes the program
secondWord = fullWord.substring(firstPositionOfAsterisk + 1, secondPositionOfAsterisk);
Simple.. read this.. String.substring(int, int)
And you'll see that
throws
IndexOutOfBoundsException - if the beginIndex is negative, or endIndex is larger than the length of this String object, or beginIndex is larger than endIndex.
the important part is or beginIndex is larger than endIndex
probably your secondPositionOfAsterisk is getting a negative (-1) value
firstWord = fullWord.substring(0, firstPositionOfAsterisk);
The above takes the first part of the string up to the first asterisk, thus it won't contain an asterisk. So this will return -1:
secondPositionOfAsterisk = firstWord.indexOf("*");
Then this will fail: (because -1 is not a valid index)
secondWord = fullWord.substring(firstPositionOfAsterisk + 1, secondPositionOfAsterisk);
I think this:
secondPositionOfAsterisk = firstWord.indexOf("*");
should be
int offset = firstWord.length()+1;
secondPositionOfAsterisk = firstWord.indexOf("*", offset);
or something like that.
Personally I think String#split is a way better option.
I want to replace this file input to a html table:
ip add St Stat Type Mode ip only class numbers
------------------------------ -- ----- ---- ---- --------------- ------ -----
ABC_127.562.200.5/32 - up ABC - 127.562.200.5 5
ABC_127.292.200.3/32 - up ABC - 127.562.200.5 4
ABC_127.262.200.13/32 - up ABC - 127.562.200.5 3
ABC:jdnsajkds
I know this will end with "ABC" but I am not able to figure out why "/" is also coming in input
import java.util.regex.*;
interface LogExample {
public static final int NUM_FIELDS = 7;
public static final String logEntryLine = "ABC_127.562.200.5/32 **space** -- **space** up **space** ABC **space** -- **space** 127.562.200.5 **space** 5 **space** ";
}
public class LogRegExp implements LogExample {
public static void main(String argv[]) {
String logEntryPattern = "";//thats i am not getting
System.out.println("Using RE Pattern:");
System.out.println(logEntryPattern);
System.out.println("Input line is:");
System.out.println(logEntryLine);
Pattern p = Pattern.compile(logEntryPattern);
Matcher matcher = p.matcher(logEntryLine);
if (!matcher.matches() ||
NUM_FIELDS != matcher.groupCount()) {
System.err.println("Bad log entry (or problem with RE?):");
System.err.println(logEntryLine);
return;
}
System.out.println("name + IP Address: " + matcher.group(1));
System.out.println("status1: " + matcher.group(2));
System.out.println("status2: " + matcher.group(3));
System.out.println("type: " + matcher.group(4));
System.out.println("mode: " + matcher.group(5));
System.out.println("IP Address: " + matcher.group(6));
System.out.println("class: " + matcher.group(7));
System.out.println("numbers: " + matcher.group(8));
}
}
Since your class column is blank, we can't do very much to extract that information. But this regex will match the 7 columns of data that you do have:
String logEntryPattern = "(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)";
We need to escape the backslash in the Java string literal.
System.out.println("name + IP Address: " + matcher.group(1));
System.out.println("status1: " + matcher.group(2));
System.out.println("status2: " + matcher.group(3));
System.out.println("type: " + matcher.group(4));
System.out.println("mode: " + matcher.group(5));
System.out.println("IP Address: " + matcher.group(6));
System.out.println("numbers: " + matcher.group(7));
Frankly, a regular expression is a little much for what you're trying to so -- just tokenizing on spaces would work just as well -- but it gets the job done.
I got the solution:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches
{
public static void main( String args[] )
{
// String to be scanned to find the pattern.
// String line = "MSEM-E-031_TO_RVBC-R-001_T1 en up TE ingr 124.252.200.2 ELSP 0";
// String pattern = "((\\-{8})+.*?)";
String line = "ADR-SSF-1008-M008 vlan en dn 10081008";
String pattern = "((\\-{6})+.*?)";
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
if (m.find( ))
{
System.out.println("Found value: " + m.group(0) );
System.out.println("Found value: " + m.group(1) );
System.out.println("Found value: " + m.group(2) );
}
else
{
System.out.println("NO MATCH");
}
}
}