Apply regex on url string - java

I have a url like this,
http://abc-xyz.com/AppName/service?id=1234&isStudent&stream&shouldUpdateRecord=Y&courseType
I want to apply a regex before making a rest call to a 3rd party system. That regex should remove all the keys without a value. i.e from this given url, my regex should remove "&isStudent", "&stream" and "&courseType" and I should be left with,
http://abc-xyz.com/AppName/service?id=1234&shouldUpdateRecord=Y
Any pointers?

I can't do it in one regex, because the number of key-only parameters is variable. But I can do it with a short program like this
public class Playground {
public static void main(String[] args) {
String testInput = "http://abc-xyz.com/AppName/service?id=1234&isStudent&stream&shouldUpdateRecord=Y&courseType";
String[] tokens = testInput.split("\\?");
String urlPrefix = tokens[0];
String paramString = tokens[1];
String[] params = paramString.split("&");
StringBuilder sb = new StringBuilder();
sb.append(urlPrefix + "?");
String keyValueRegex = "(\\w+)=(\\w+)";
String amp = ""; // first time special
for (String param : params) {
if (param.matches(keyValueRegex)) {
sb.append(amp + param);
amp = "&"; // second time and onwards
}
}
System.out.println(sb.toString());
}
}
The output of this program is this:
http://abc-xyz.com/AppName/service?id=1234&shouldUpdateRecord=Y

Related

How to read colon seperated values from txt file in java

I am trying to read in the data from a text file that is formatted like this:
Operation: ADDITION Attempts: 3
The data I'm trying to read in is the operation and the number of attempts for each line so for example ADDITION and the number 3
This is as far as I could get and I'm still not certain.
File inputFile = new File("mathFile.txt");
Scanner input = new Scanner(inputFile);
while(input.hasNext())
{
String token = input.nextLine();
String[] details = token.split("Operation:");
String operation = details[0];
}
The simplest option is to split on spaces:
String[] parts = token.split(" ");
String operation = parts[1];
String attempts = parts[3];
If you want to get fancier, you can use Regex:
String token = "Operation: ADDITION Attempts: 3";
Matcher matcher = Pattern.compile("^Operation: (\\w+) Attempts: (\\d+)$").matcher(token);
if (matcher.find()) {
String operation = matcher.group(1);
String attempts = matcher.group(2);
}
// Model: line representation
public final class MathFileLine {
private final String operation;
private final int attempts;
public MathFileLine(String operation, int attempts) {
this.operation = operation;
this.attempts = attempts;
}
}
// client code
public static void main(String... args) throws IOException {
List<MathFileLine> lines = readMathFile(Paths.get("mathFile.txt"));
}
#1: Use Stream to read lines with RegEx
public static List<MathFileLine> readMathFile(Path path) throws IOException {
final Pattern pattern = Pattern.compile("^Operation:\\s+(?<operation>\\w+)\\s+Attempts:\\s+(?<attempts>\\d+)$");
return Files.lines(path)
.map(pattern::matcher)
.filter(Matcher::matches)
.map(matcher -> new MathFileLine(matcher.group("operation"), Integer.parseInt(matcher.group("attempts"))))
.collect(Collectors.toList());
}
#2: Use Scanner with custom delimiter to read pairs
public static List<MathFileLine> readMathFile(Path path) throws IOException {
try (Scanner scan = new Scanner(path.toFile())) {
scan.useDelimiter("\\s*(?:Operation:|Attempts:)?\\s+");
List<MathFileLine> lines = new LinkedList<>();
while (scan.hasNext()) {
lines.add(new MathFileLine(scan.next(), scan.nextInt()));
}
return lines;
}
}
There are many ways you can read a text file and split the lines based on some delimiter. In addition to all the other answers here, following is yet another answer that is succinct and self-explanatory.
(1) Read the lines of a file
List<String> lines = Files.lines(Paths.get("mathFile.txt")).collect(Collectors.toList());
(2) Parse what you want from each line
List<String> operations = lines.stream().map(line -> line.split("Operation:")[0]).collect(Collectors.toList());

How to split the string from a file?

I have a simple text file with information in it called logindata.txt . And it looks like this:
username1:password1:username2:password2
The plan is to split the line at the " : " symbol.
This is my code so far...
(...)
final StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
try {
String line;
while ((line = br.readLine()) != null) {
text.append(text);
//stuff over here ?
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
This works perfectly fine if my file only has one word in it.
But I want to use the file to store all the usernames and passwords (This is only for learning purposes I know it's a bit stupid) in the end like this:
(...)
login_button.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
if (username.getText().toString().equals(text.toString()) && password.getText().toString().equals(text.toString()))
//Stuff happening here if the username & password is correct...
(...)
I'm completely stuck and have tried many examples for splitting a string and none seem to work.
In your case I would like to use a Map<Username, Password> with Pattern like this :
String line = "username1:password1:username2:password2";
Map<String, String> userPass = new HashMap<>();
Pattern pattern = Pattern.compile("([^:]+):([^:]+)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
userPass.put(matcher.group(1), matcher.group(2));
}
System.out.println(userPass);
Outputs
{username2=password2, username1=password1}
If you want to check if the user exist or not, you can use :
String username = "username1";
String password = "password1";
if(userPass.containsKey(username) && userPass.get(username).equals(password)){
//User exist
}
In case you values can be repeated you can use another structure or create a new Object which hold username and password, instead of a map
a general code would be for splitting text would be
class Main {
public static void main(String[] args) {
String text = "username1:password1:username2:password2";
String[] vals = text.split(":");
for (String temp: vals){
System.out.println(temp);
}
}
}
To split a String in java, you could use String#split(string regex).
In your case, after have the file read into a String, you could put all pairs of username/password into a HashMap for lookup.
String text = "username1:password1:username2:password2"; // you would read it from the file
String[] segments = text.split(":"); // split the string with ":"
Map<String, String> userPassMap = new HashMap<>(); // initialize the map to store user info
for (int i = 0; i < segments.length; i+=2) {
userPassMap.put(segments[i], segments[i+1]);
}
And for your login validation
login_button.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
String user = username.getText().toString().trim(); // trim() to get rid of heading and trailing empty spaces
String pass = password.getText().toString().trim();
if (userPassMap.containsKey(user) && userPassMap.get(user).equals(pass)) {
//Stuff happening here if the username & password is correct...
}
(...)

How to divide URL without Using Collections in Java

Can any one help me How to divide URL without using collections.
Example: I have URL(https://localhost:8080/prodpat/admin/page1)
Have to divide as follows
https
localhost
8080
prodapt
admin
page1
1. You would be able to find a solution using split(":|/")
String url = "https://localhost:8080/prodpat/admin/page1";
String[] array = url.split("/|:|://");
String https = array[0]; // https
String localhost = array[1]; // localhost
String port = array[2]; // 8080
String prodapt = array[3]; // prodpat
String admin = array[4]; // admin
String page1 = array[5]; // page1
2. Or use java.net.URL, and get back the element you need :
public static void main(String[] args) {
try {
URL url = new URL("https://localhost:8080/prodpat/admin/page1");
String https = url.getProtocol(); // https
String localhost = url.getHost(); // localhost
int port = url.getPort(); // 8080
String[] path = url.getPath().split("/"); // /prodpat/admin/page1
String prodapt = path[1]; // prodpat
String admin = path[2]; // admin
String page1 = path[3]; //page1
} catch (MalformedURLException ex) {
Logger.getLogger(Test3.class.getName()).log(Level.SEVERE, null, ex);
}
}
You can try this
public class SplitURL {
public static void main(String[] args) {
String url = "https://localhost:8080/prodpat/admin/page1";
String[] urlSplitData = url.split("[^A-Za-z0-9]");
System.out.println(java.util.Arrays.toString(urlSplitData));
StringBuilder sb = new StringBuilder();
for(int i=0; i<urlSplitData.length; i++) {
if(urlSplitData[i].trim().length() != 0) {
sb.append(urlSplitData[i]+"_");
}
}
System.out.println(java.util.Arrays.toString(sb.toString().split("_")));
}
}
Explanation :
The regex provided to split the string will act like any special character.
Now when you split the URL which is having special characters one after the other (like ://), the split array will be not sufficient to full fill the requirement.
So again append the array content (whose length is not zero even after trim not an empty string and not a string with only whitespace) to a StringBuilder, with any common seperator like _.
Finally split the StringBuilder after converting to a String, using the appended common separator.
That final array will be what you need.
You can try this.
URL url = new URL("https://localhost:8080/prodpat/admin/page1");
String[] tokens = url.toString().split("://|/|:");
for (int i =0 ; i < tokens.length ; i++){
System.out.println( tokens[i] );
}

How to replace a substring without using replace() methods

I am trying to convert a text document to shorthand, without using any of the replace() methods in java. One of the strings I am converting is "the" to "&". The problem is, that I do not know the substring of each word that contains the "the" string. So how do I replace that part of a string without using the replace() method?
Ex: "their" would become "&ir", "together" would become "toge&r"
This is what I have started with,
String the = "the";
Scanner wordScanner = new Scanner(word);
if (wordScanner.contains(the)) {
the = "&";
}
I am just not sure how to go about the replacement.
You could try this :
String word = "your string with the";
word = StringUtils.join(word.split("the"),"&");
Scanner wordScanner = new Scanner(word);
I do not get your usage of Scanner for this, but you can read each character into a buffer (StringBuilder) until you read "the" into the buffer. Once you've done that, you can delete the word and then append the word you want to replace with.
public static void main(String[] args) throws Exception {
String data = "their together the them forever";
String wordToReplace = "the";
String wordToReplaceWith = "&";
Scanner wordScanner = new Scanner(data);
// Using this delimiter to get one character at a time from the scanner
wordScanner.useDelimiter("");
StringBuilder buffer = new StringBuilder();
while (wordScanner.hasNext()) {
buffer.append(wordScanner.next());
// Check if the word you want to replace is in the buffer
int wordToReplaceIndex = buffer.indexOf(wordToReplace);
if (wordToReplaceIndex > -1) {
// Delete the word you don't want in the buffer
buffer.delete(wordToReplaceIndex, wordToReplaceIndex + wordToReplace.length());
// Append the word to replace the deleted word with
buffer.append(wordToReplaceWith);
}
}
// Output results
System.out.println(buffer);
}
Results:
&ir toge&r & &m forever
This can be done without a Scanner using just a while loop and StringBuilder
public static void main(String[] args) throws Exception {
String data = "their together the them forever";
StringBuilder buffer = new StringBuilder(data);
String wordToReplace = "the";
String wordToReplaceWith = "&";
int wordToReplaceIndex = -1;
while ((wordToReplaceIndex = buffer.indexOf(wordToReplace)) > -1) {
buffer.delete(wordToReplaceIndex, wordToReplaceIndex + wordToReplace.length());
buffer.insert(wordToReplaceIndex, wordToReplaceWith);
}
System.out.println(buffer);
}
Results:
&ir toge&r & &m forever
You can use Pattern and Matcher Regex:
Pattern pattern = Pattern.compile("the ");
Matcher matcher = pattern.matcher("the cat and their owners");
StringBuffer sb = new StringBuffer();
while(matcher.find()){
matcher.appendReplacement(sb, "& ");
}
matcher.appendTail(sb);
System.out.println(sb.toString());

Splitting a String without spaces

I have the following string which is generated by an external program (OpenVAS) and returned to my program successfully as a string.
<create_target_response id="b4c8de55-94d8-4e08-b20e-955f97a714f1" status_text="OK, resource created" status="201"></create_target_response>
I am trying to split the string to give me the "b4c8d....14f1" without the inverted commas. I have tried all sorts of escape methods and keep getting the else method "String does not contain a Target ID". I have tried removing the IF statement checking for the string, but continue to have the same issue. The goal is to get my id string into jTextField6. String Lob contains the full string as above.
if (Lob.contains("id=\"")){
// put the split here
String[] parts = Lob.split("id=\"");
String cut1 = parts[1];
String[] part2 = cut1.split("\"");
String TaskFinal = part2[0];
jTextField6.setText(TaskFinal);
}
else {
throw new IllegalArgumentException("String does not contain a Target ID");
}
} catch (IOException e) {
e.printStackTrace();
}
It seems I only need to escape the " and not the = (Java kicks up an error if i do)
Thanks in advance
EDIT: Code as it stands now using jSoup lib - The 'id' string won't display. Any ideas?
Thanks
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
String TargIP = jTextField1.getText(); // Get IP Address
String TargName = jTextField5.getText(); // Get Target Name
String Vag = "8d32ad99-ac84-4fdc-b196-2b379f861def";
String Lob = "";
final String dosCommand = "cmd /c omp -u admin -w admin --xml=\"<create_target><name>" + TargName + "</name><hosts>" + TargIP + "</hosts></create_target>\"";
3</comment><config id='daba56c8-73ec-11df-a475-002264764cea'/><target id='" + Vag + "'/></create_task>\"";
final String location = "C:\\";
try {
final Process process = Runtime.getRuntime().exec(
dosCommand + " " + location);
final InputStream in = process.getInputStream();
int ch;
while((ch = in.read()) != -1) {
System.out.print((char)ch);
Lob = String.valueOf((char)ch);
jTextArea2.append(Lob);
}
} catch (IOException e) {
e.printStackTrace();
}
String id = Jsoup.parse(Lob).getAllElements().attr("id");
System.out.println(id); // This doesn't output?
}
Split on the basis of ". You can get all the key values.
String str = "<create_target_response id=\"b4c8de55-94d8-4e08-b20e-955f97a714f1\" status_text=\"OK, resource created\" status=\"201\"></create_target_response>";
String[] tokens = str.split("\\\"");
System.out.println(tokens[1]);
System.out.println(tokens[5]);
output:
b4c8de55-94d8-4e08-b20e-955f97a714f1
201
This will get you your job id more easily:
int idStart = Lob.indexOf("id=")+("id=\"").length();
System.out.println(Lob.substring(idStart,Lob.indexOf("\"",idStart)));
Everyone's telling you to use an XML parser (and they're right) but noone's showing you how.
Here goes:
String lob = ...
Using Jsoup from http://jsoup.org, actually an HTML parser but also handles XML neatly:
String id = Jsoup.parse(lob).getAllElements().attr("id");
// b4c8de55-94d8-4e08-b20e-955f97a714f1
With built-in Java XML APIs, less concise but no addtional libraries:
Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(new InputSource(new StringReader(lob)));
String id = dom.getDocumentElement().getAttribute("id");
// b4c8de55-94d8-4e08-b20e-955f97a714f1
This is a lot simpler than you're making it, to my mind. First, split on space, then check if an = is present. If it is, split on the =, and finally remove the " from the second token.
The tricky bit is the spaces inside of the "". This will require some regular expressions, which you can work out from this question.
Example
String input; // Assume this contains the whole string.
String pattern; // Have fun working out the regex.
String[] values = input.split(pattern);
for(String value : values)
{
if(value.contains("=")) {
String[] pair = value.split("=");
String key = pair[0];
String value = pair[1].replaceAll("\"");
// Do something with the values.
}
}
Advantage of my approach
Is that provided the input follows the format of key="value" key="value", you can parse anything that comes through, rather than hard coding the name of the attributes.
And if this is XML..
Then use an XML parser. There is a good (awesome) answer that explains why you shouldn't be using Stringmanipulation to parse XML/HTML. Here is the answer.
You can use a regex to extract what is needed; what is more, it looks like the value of id is a UUID. Therefore:
private static final Pattern PATTERN
= Pattern.compile("\\bid=\"([^\"]+)\"");
// In code...
public String getId(final String input)
{
final Matcher m = PATTERN.matcher(input);
if (!m.find())
throw new IllegalArgumentException("String does not contain a Target ID");
final String uuid = m.group(1);
try {
UUID.fromString(uuid);
} catch (IllegalArgumentException ignored) {
throw new IllegalArgumentException("String does not contain a Target ID");
}
return uuid;
}

Categories

Resources