Write text to .bat file at specified position in Java - java

I have a requirement to edit the .bat file with Java.
The file contains following line of text
testrunner.bat -ParId=12810 -PsysDate=2014-07-03 "C:\SOAP METHODS\DELINQ-soapui-project.xml"
Here I have a string -ParId=12810 and -PsysDate=2014-07-03, in this I need to write the new content after = sign, i.e. I need to assign different values to -ParId and -PsysDate variables.

What's wrong with rewriting the complete file?

I don't know much about regex, in fact i almost never used it, but you can utilizing regex for your problem, something like:
class RegexExample {
public static void main(String[] args) {
String input = "testrunner.bat -ParId=12810 -PsysDate=2014-07-03 'C:\\SOAP METHODS\\DELINQ-soapui-project.xml'";
input = input.replaceAll("ParId=[0-9]+","ParId=newValueID");
input = input.replaceAll("PsysDate=\\w+\\-\\w+\\-\\w+","PsysDate=newValueDate");
System.out.println(input);
}
}
I know it is not the most efficient or pretty, but you can start from there, many references found in Google though :)

If the file always contains the same text(without the parameters) you could do:
String formatstr = "testrunner.bat -ParId=%d -PsysDate=%s \"C:\SOAP METHODS\DELINQ-soapui-project.xml\"";
String output = String.format(formatstr,id,datestring);
// write output to file

Related

Include comma in a field value of csv (delimeter as comma) in java

I want to create a csv file in which delimiter is comma seperated.While csv is read it make s5 string in comma seperation. Want to keep s5 string in single column.
String s1="quick";
String s2="brown";
String s3="fox";
String s4="jump";
String s5="over,the,lazy,dog";
String csvRecord = String.format("%s,%s,%s,%s,%s", s1,s2,s3,s4,s5);
Can anybody help me out, as i am new to strings.
I think you need to add them in a double string.
Try this:
String s5="\"over,the,lazy,dog\"";
Just as other answers mentioned, you have to actually consider many special cases and the most typical two special cases will be: comma and double quotes.
As Chewtoy enclosed, the CSV wiki has clearly specify the format as:
Year,Make,Model,Description,Price
1997,Ford,E350,"ac, abs, moon",3000.00
1999,Chevy,"Venture ""Extended Edition""","",4900.00
1999,Chevy,"Venture ""Extended Edition, Very Large""",,5000.00
1996,Jeep,Grand Cherokee,"MUST SELL!
air, moon roof, loaded",4799.00
To handle these two cases, you can try something as:
public class CsvAddComma {
public static void main(String... args) {
List<String> list = new ArrayList<>();
list.add("quick");
list.add("over,the,lazy,dog");
list.add("Venture \"Extended Edition, Very Large\"");
list.stream()
.map(s -> convertToCsvFormat(s))
.forEach(System.out::println);
}
private static String convertToCsvFormat(String input) {
if (input.contains("\"")) {
input = input.replaceAll("\"", "\"\"");
}
if (input.contains(",")) {
input = String.format("\"%s\"", input);
}
return input;
}
}
And the output:
quick
"over,the,lazy,dog"
"Venture ""Extended Edition, Very Large"""
As for other special cases, you need to handle them according to your current case. Perhaps they can be ignored, perhaps not.
To include a delimiter in the data, you have to enclose the field with double quotes in the resulting csv:
quick,brown,fox,jump,"over,the,lazy,dog"
If there are double quotes inside some fields those have to be escaped:
123,"24"" monitor, Samsung",456 // Windows style
123,"24\" monitor",456 // Linux style
You don't have to quote all the fields, only those containing a delimiter or a double quote (or a newline).
See RFC4180 for more details on the csv common format.
Unless you are toying with some assignment you absolutely NEED a CSV library to handle this for you. You also need to care about line endings and other quotes inside the values, not only the delimiter
Try the following code with univocity-parsers:
CsvWriterSettings settings = new CsvWriterSettings();
CsvWriter writer = new CsvWriter(settings);
String result = writer.writeRowToString(s1,s2,s3,s4,s5);
Hope this helps.
Disclaimer: I'm the author of this library. It's open source and free (Apache 2.0 license)

How to convert contains to equals.ignorecase?

I am reading a text file into my program, and having the user search for a string. How can I make this so its case-insensitive? Here is a snippet of my code:
while (str1.hasNextLine())
{
String line = str1.nextLine();
line = line.replace(";", " ");
if(line.contains(Val))
{
System.out.println(line);
}
}
Val is the string variable. It is the string that the user entered, and the string that, if found in the text file, will print out on the line. But I need it to be case-insensitive. For some reason when I use equals.IgnoreCase it doesn't work.
In this scenario, make everything a unified case, and compare.
if (line.toLowerCase().contains(Val.toLowerCase())) {
// logic
}
There are limitations on what contains can do. It only checks CharSequences and does so in a case-sensitive fashion. By introducing a common case, this eliminates the case sensitivity issue.

Fastest way to parse txt file in Java

I have to parse a txt file for a tax calculator that has this form:
Name: Mary Jane
Age: 23
Status: Married
Receipts:
Id: 1
Place: Restaurant
Money Spent: 20
Id: 2
Place: Mall
Money Spent: 30
So, what i have done so far is:
public void read(File file) throws FileNotFoundException{
Scanner scanner = new Scanner(file);
String[] tokens = null;
while(scanner.hasNext()){
String line= scanner.nextLine();
tokens = line.split(":");
String lastToken = tokens[tokens.length - 1];
System.out.println(lastToken);
So, I want to access only the second column of this file (Mary Jane, 23, Married) to a class taxpayer(name, age, status) and the receipts' info to an Arraylist.
I thought of taking the last token and save it to an String array, but I can't do that because I can't save string to string array. Can someone help me? Thank you.
The fastest way, if your data is ASCII and you don't need charset conversion, is to use a BufferedInputStream and do all the parsing yourself -- find the line terminators, parse the numbers. Do NOT use a Reader, or create Strings, or create any objects per line, or use parseInt. Just use byte arrays and look at the bytes. It's a little messier, but pretend you're writing C code, and it will be faster.
Also give some thought to how compact the data structure you're creating is, and whether you can avoid creating an object per line there too by being clever.
Frankly, I think the "fastest" is a red herring. Unless you have millions of these files, it is unlikely that the speed of your code will be relevant.
And in fact, your basic approach to parsing (read line using Scanner, split line using String.split(...) seems pretty sound.
What you are missing is that the structure of your code needs to match the structure of the file. Here's a sketch of how I would do it.
If you are going to ignore the first field of each line, you need a method that:
reads a line, skipping empty lines
splits it, and
returns the second field.
If you are going to check that the first field contains the expected keyword, then modify the method to take a parameter, and check the field. (I'd recommend this version ...)
Then call the above method in the correct pattern; e.g.
call it 3 times to extract the name, age and marital status
call it 1 time to skip the "reciepts" line
use a while loop to call the method 3 times to read the 3 fields for each receipt.
First why do you need to invest time into the fastest possible solution? Is it because the input file is huge? I also do not understand how you want to store result of parsing? Consider new class with all fields you need to extract from file per person.
Few tips:
- Avoid unnecessary per-line memory allocations. line.split(":") in your code is example of this.
- Use buffered input.
- Minimize input/output operations.
If these are not enough for you try to read this article http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly
Do you really need it to be as fast as possible? In situations like this, it's often fine to create a few objects and do a bit of garbage collection along the way in order to have more maintainable code.
I'd use two regular expressions myself (one for the taxpayer and another for the receipts loop).
My code would look something like:
public class ParsedFile {
private Taxpayer taxpayer;
private List<Receipt> receipts;
// getters and setters etc.
}
public class FileParser {
private static final Pattern TAXPAYER_PATTERN =
// this pattern includes capturing groups in brackets ()
Pattern.compile("Name: (.*?)\\s*Age: (.*?)\\s*Status: (.*?)\\s*Receipts:", Pattern.DOTALL);
public ParsedFile parse(File file) {
BufferedReader reader = new BufferedReader(new FileReader(file)));
String firstChunk = getNextChunk(reader);
Taxpayer taxpayer = parseTaxpayer(firstChunk);
List<Receipt> receipts = new ArrayList<Receipt>();
String chunk;
while ((chunk = getNextChunk(reader)) != null) {
receipts.add(parseReceipt(chunk));
}
return new ParsedFile(taxpayer, receipts);
}
private TaxPayer parseTaxPayer(String chunk) {
Matcher matcher = TAXPAYER_PATTERN.matcher(chunk);
if (!matcher.matches()) {
throw new Exception(chunk + " does not match " + TAXPAYER_PATTERN.pattern());
}
// this is where we use the capturing groups from the regular expression
return new TaxPayer(matcher.group(1), matcher.group(2), ...);
}
private Receipt parseReceipt(String chunk) {
// TODO implement
}
private String getNextChunk(BufferedReader reader) {
// keep reading lines until either a blank line or end of file
// return the chunk as a string
}
}

String replace and output in Java [duplicate]

This question already has answers here:
Java String replace not working [duplicate]
(6 answers)
Closed 9 years ago.
I got a query, please see code below:
public void readFile(String path,String pathName,int num){
try{
PrintWriter out2=new PrintWriter(new PrintWriter(path));
File a=new File(pathName);
Scanner b=new Scanner(a);
while(b.hasNextLine()){
String message=b.nextLine();
Scanner h=new Scanner(message);
while(h.hasNext()){
String f=h.next();
if (f.equals("are")){
f.replace("are","ARE");
}
}
out2.printf("%s",message);
out2.println();
.......
The file content for scanner read is
who are you?
how are you?
what is up!
However, when I run the above codes and the output to the new file are the same with the input file, it means the "are" not replaced by "ARE", I have no idea which part is wrong, please advise, thanks guys!
This line just outputs the message unchanged to the new file.
out2.printf("%s",message);
Also the loop is strange too: why do you read it word by word, and then use String.replace()? You could do it line by line, using String.replaceAll():
while(h.hasNextLine()){
String message=b.nextLine();
out2.printf("%s",message.replaceAll("(^|\\W)are(\\W|$)"," ARE "));
}
The (^|\\W)are(\\W|$) string is a regular expression, having the meaning to match all content, that starts with either being the start of the string ^, or a non-word character (\\W), the string are, and ends with a non-word character or the end of line($)...
As scanner has whitespace as the default delimiter, it might be ever better to use (^|\\s)are(\\s|$), however both these will replace the whitespace before and after "ARE" with a single space ()...
Also, keep in mind, that String.replace does not mutate the input String... You have to assign the result, or use it any other way, like pass it to a function...
String is final and immutable, which is the same.
so f.replace("are","ARE"); must be inserted into a new or not variable.
f = f.replace("are","ARE");
I do not understand why you are doing that. Here is an alternative approach:
Get a BufferedReader to read the file.
While there is data in the file, read the lines.
If line.contains("are") then line = line.replace("are","ARE")
println(line)
As to why your code did not work:
In this line, f.replace("are","ARE"); You forgot to get the output.
Make it as such: message = f.replace("are","ARE");
Another option is to use StringBuffer or StringBuilder
Strings are immutable. Therefore, you can not run the replace method on object f and expect its value to be changed since the replace method of a string object will simply return a new String object.
either use a StringBuilder instead, or use :
f = f.replace
On the other hand, StringBuilder objects are mutable. Therefore, you can run the StringBuilder version of the replace method directly on the object if you choose that route instead.

How to set a java string variable equal to "htp://website htp://website " [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
so I have a large list of websites and I want to put them all in a String variable. I know I can not individually go to all of the links and escape the //, but is there is over a few hundred links. Is there a way to do a "block escape", so everything in between the "block" is escaped? This is an example of what I want to save in the variable.
String links="http://website http://website http://website http://website http://website http://website"
Also can anyone think of any other problems I might run into while doing this?
I made it htp instead of http because I am not allowed to post "hyperlinks" according to stack overflow as I am not at that level :p
Thanks so much
Edit: I am making a program because I have about 50 pages of a word document that is filled with both emails and other text. I want to filter out just the emails. I wrote the program to do this which was very simple, not I just need to figure away to store the pages in a string variable in which the program will be run on.
Your question is not well-written. Improve it, please. In its current format it will be closed as "too vague".
Do you want to filter e-mails or websites? Your example is about websites, you text about e-mails. As I don't know and I decided to try to help you anyway, I decided to do both.
Here goes the code:
private static final Pattern EMAIL_REGEX =
Pattern.compile("[A-Za-z0-9](:?(:?[_\\.\\-]?[a-zA-Z0-9]+)*)#(:?[A-Za-z0-9]+)(:?(:?[\\.\\-]?[a-zA-Z0-9]+)*)\\.(:?[A-Za-z]{2,})");
private static final Pattern WEBSITE_REGEX =
Pattern.compile("http(:?s?)://[_#\\.\\-/\\?&=a-zA-Z0-9]*");
public static String readFileAsString(String fileName) throws IOException {
File f = new File(fileName);
byte[] b = new byte[(int) f.length()];
InputStream is = null;
try {
is = new FileInputStream(f);
is.read(b);
return new String(b, "UTF-8");
} finally {
if (is != null) is.close();
}
}
public static List<String> filterEmails(String everything) {
List<String> list = new ArrayList<String>(8192);
Matcher m = EMAIL_REGEX.matcher(everything);
while (m.find()) {
list.add(m.group());
}
return list;
}
public static List<String> filterWebsites(String everything) {
List<String> list = new ArrayList<String>(8192);
Matcher m = WEBSITE_REGEX.matcher(everything);
while (m.find()) {
list.add(m.group());
}
return list;
}
To ensure that it works, first lets test the filterEmails and filterWebsites method:
public static void main(String[] args) {
System.out.println(filterEmails("Orange, pizza whatever else joe#somewhere.com a lot of text here. Blahblah blah with Luke Skywalker (luke#starwars.com) hfkjdsh fhdsjf jdhf Paulo <aaa.aaa#bgf-ret.com.br>"));
System.out.println(filterWebsites("Orange, pizza whatever else joe#somewhere.com a lot of text here. Blahblah blah with Luke Skywalker (http://luke.starwars.com/force) hfkjdsh fhdsjf jdhf Paulo <https://darth.vader/blackside?sith=true&midclorians> And the http://www.somewhere.com as x."));
}
It outputs:
[joe#somewhere.com, luke#starwars.com, aaa.aaa#bgf-ret.com.br]
[http://luke.starwars.com/force, https://darth.vader/blackside?sith=true&midclorians, http://www.somewhere.com]
To test the readFileAsString method:
public static void main(String[] args) {
System.out.println(readFileAsString("C:\\The_Path_To_Your_File\\SomeFile.txt"));
}
If that file exists, its content will be printed.
If you don't like the fact that it returns List<String> instead of a String with items divided by spaces, this is simple to solve:
public static String collapse(List<String> list) {
StringBuilder sb = new StringBuilder(50 * list.size());
for (String s : list) {
sb.append(" ").append(s);
}
sb.delete(0, 1);
return sb.toString();
}
Sticking all together:
String fileName = ...;
String webSites = collapse(filterWebsites(readFileAsString(fileName)));
String emails = collapse(filterEmails(readFileAsString(fileName)));
I suggest that you save your Word document as plain text. Then you can use classes from the java.io package (such as Scanner to read the text).
To solve the issue of overwriting the String variable each time you read a line, you can use an array or ArrayList. This is much more ideal than holding all the web addresses in a single String because you can easily access each address individually whenever you like.
For your first problem, take all the text out of word, put it in something that does regular expressions, use regular expressions to quote each line and end each line with +. Now edit the last line and change + to ;. Above the first line write String links =. Copy this new file into your java source.
Here's an example using regexr.
To answer your second question (thinking of problems) there is an upper limit for a Java string literal if I recall correctly 2^16 in length.
Oh and Perl was basically written for you to do this kind of thing (take 50 pages of text and separate out what is a url and what is an email)... not to mention grep.
I'm not sure what kind of 'list of websites' you're referring to, but for eg. a comma-separated file of websites you could read the entire file and use the String split function to get an array, or you could use a BufferedReader to read the file line by line and add to an ArrayList.
From there you can simply loop the array and append to a String, or if you need to:
do a "block escape", so everything in between the "block" is escaped
You can use a Regular Expression to extract parts of each String according to a pattern:
String oldString = "<someTag>I only want this part</someTag>";
String regExp = "(?i)(<someTag.*?>)(.+?)(</someTag>)";
String newString = oldString.replaceAll(regExp, "$2");
The above expression would remove the xml tags due to the "$2" which means you're interested in the second group of the expression, where groups are identified by round brackets ( ).
Using "$1$3" instead should then give you only the surrounding xml tags.
Another much simpler approach to removing certain "blocks" from a String is the String replace function, where to remove the block you could simply pass in an empty string as the new value.
I hope any of this helps, otherwise you could try to provide a full example with you input "list of websites" and the output you want.

Categories