I am using Selenium to test web-pages and want to make a simpler way to update the test-cases (not important for the problem).
I loop through lines now with this:
driver.get("http://vg.no"); //open the web page
try {
BufferedReader reader = new BufferedReader(new FileReader("//Users//file.txt"));
try {
String line = null;
while ((line = reader.readLine()) != null) {
driver.findElement(By.cssSelector(line)).click();; //find and click on the data specified in every line in the document
}
} finally {
reader.close();
}
} catch (IOException ioe) {
System.err.println("oops " + ioe.getMessage());
}
Textfile content example now:
a[href*='//nyheter//meninger//']
img[class*='logo-red']
img[class*='article-image']
I want to rebuild it to a solution that start different commands based on regex expressions.
I try to get it to work this way:
vg.no //this will start driver.get("vg.no")
img[class*='logo-red'] //this will start driver.findElement(By.cssSelector("img[class*='logo-red']")).click()
img[class*='article-image']
ItAvisen.no
img[class*='article-image']
img[class*='article-image']
Is there a way I can use regex to start dirrerent parts of the code based on content in the textfile, and use part of the content in the textfile as variables?
It works this way after feedback from cvester:
Finding matches for img[class*='logo-red']
String regexp = "img\\[class\\*=\\'*\\'(.*)\\]";
boolean match = line.matches(regexp);
Will it still be line based?
In that case you can just read line by line and use the String.matches(String regex) for each case you identify.
If you can specify more specific information I might be able to give you a better solution.
Related
My code works fine however it prints the values side by side instead of under each other line by line. Like this:
iatadult,DDD,
iatfirst,AAA,BBB,CCC
I have done a diligent search on stackoverflow and none of my solution's seem to work. I know that I have to make the change while the looping is going on. However none of the examples I have seen have worked. Any further understanding or techniques to achieve my goal would be helpful. Whatever I am missing is probably very small. Please help.
String folderPath1 = "C:\\PayrollSync\\client\\client_orginal.txt";
File file = new File (folderPath1);
ArrayList<String> fileContents = new ArrayList<>(); // holds all matching client names in array
try {
BufferedReader reader = new BufferedReader(new FileReader(file));// reads entire file
String line;
while (( line = reader.readLine()) != null) {
if(line.contains("fooa")||line.contains("foob")){
fileContents.add(line);
}
//---------------------------------------
}
reader.close();// close reader
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println(fileContents);
Add a Line Feed before you add to fileContents.
fileContents.add(line+"\n");
By printing the list directly as you are doing you are invoking the method toString() overridden for the list which prints the contents like this:
obj1.toString(),obj2.toString() .. , objN.toString()
in your case the obj* are of type String and the toString() override for it returns the string itself. That's why you are seeing all the strings separated by comma.
To do something different, i.e: printing each object in a separate line you should implement it yourself, and you can simply append the new line character('\n') after each string.
Possible solution in java 8:
String result = fileContents.stream().collect(Collectors.joining('\n'));
System.out.println(result);
A platform-independent way to add a new line:
fileContents.add(line + System.lineSeparator);
Below is my full answer. Thanks for your help stackoverflow. It took me all day but I have a full solution.
File file = new File (folderPath1);
ArrayList<String> fileContents = new ArrayList<>(); // holds all matching client names in array
try {
BufferedReader reader = new BufferedReader(new FileReader(file));// reads entire file
String line;
while (( line = reader.readLine()) != null) {
String [] names ={"iatdaily","iatrapala","iatfirst","wpolkrate","iatjohnson","iatvaleant"};
if (Stream.of(names).anyMatch(line.trim()::contains)) {
System.out.println(line);
fileContents.add(line + "\n");
}
}
System.out.println("---------------");
reader.close();// close reader
} catch (Exception e) {
System.out.println(e.getMessage());
}
I have a html file which I have to search line by line and look for a particular string and then take some actions accordingly.
The problem is that the string is being matched to the entire line of the each line of the html file.
So if there are some spaces before the actual string in a given line, the match turns out to be false, even though it should be positive.
package read_txt;
import java.io.*;
class FileRead
{
public static void main(String args[])
{
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("textfile.html");
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
//String a = "media query";
switch (strLine) {
case "#media query" :
System.out.println("media query found");
System.out.println("html file responsive");
break;
// default :
// System.out.println("html file unresponsive");
//break;
}
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
In my code above, I am searching for a String "media query". Now suppose this is the html file being searched :
The codes works fine for this html file, but now suppose we have this html file :
The string match does not work although a media query string is present, but if I change the matched string to " media query" instead of "media query", it works again.
Any idea how can I ignore the blank spaced occurring before appearance of any text in a line?
In this case, I would think that using "switch" is not the right way to go.
You might use
if (strLine.contains("media query"))
but that will fail if the line has "media query" (two spaces instead of one).
So, you best bet might be to use a regular expression.
You could use endsWith, e.g.
if (strLine.endsWith("media query")) { ...
In cases, where the searched string could be somewhere in the middle of line you could use indexOf, e.g.
if (strLine.indexOf("medial quera") >= 0) { ...
I have a file that contains a header with comments (e.g. [Comment] This is a comment) and a subsequent data section. The data starts at "Mk1=".
The program I am working on should:
Copy the header contents
Search and replace only in the data section of the file
Write header and data to a new file
I am currently using:
StringBuffer
Scanner
regex.Pattern;
In my code so far (reduced to its essentials):
public static void main(String[] args) {
File file = readFile("file.ext");
Scanner inputScanner = null;
try {
inputScanner = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String currentLine = "";
while(inputScanner.hasNext()) {
currentLine = inputScanner.findInLine(regexpPattern);
if (currentLine != null){
fileOutput.append(currentLine + "\n");
}
}
}
Because the Scanner works like a queue, I have trouble figuring out what strategy I should use. I have found examples of using a Matcher instead of a Scanner. To my understanding I also have to work with boolean flags, because of the queue-like structure of Scanner. The findInHorizon() method does not seem helpful as I want the reg exp only to apply beyond the horizon. Is there perhaps a "hack" for the delimiter of the Scanner, assuming I know the series of characters of the header start and end?
File Example
[Comment]
Text goes here.
[Another Comment]
;Instructions: Below you will find Mk1= where the data can be assigned.
;More text.
Mk1=data
Mk2=data
Mk3=data
What strategy should I use?
Assuming you can use java.nio.file.Files (since Java 1.7) and your text file isn't too big, I'd read all lines at once and go for the Matcher:
Charset charset = Charset.forName("UTF-8");
List<String> lines = Files.readAllLines(file.toPath(), charset);
for (String line : lines) {
Matcher matcher = regexpPattern.matcher(line);
if (matcher.matches()) {
// do something
}
}
Using regex groups will prove useful for retrieving parameter-value pairs:
Pattern dataPattern = Pattern.compile("^Mk(\\d+)=(.*)$");
Matcher dataMatcher = dataPattern.matcher(line);
int mk = Integer.parseInt(dataMatcher.group(1));
String data = dataMatcher.group(2);
Parsing is a two step process: You have a tokenizer which recognizes patterns in the input and a parser which reads tokens but also has a state to know where it is.
You can use regexp for the "tokenize" part of the problem but you also need a parser which remembers "I have seen [Comment]" so it knows what could/should be next.
Related:
https://class.coursera.org/compilers/lecture
I'm trying to basically make a simple Test Generator. I want a button to parse a text file and add the records to my database. The questions and answers are in a text file. I have been searching the net for examples but I can't find one that matches my situation.
The text file has header information that I want to ignore up until the line that starts with "~ End of Syllabus". I want "~ End of Syllabus" to indicate the beginning of the questions. A couple of lines after that look for a line with a "(" in the seventh character position. I want that to indicate the Question Number line. The Question Number line is unique in that the "(" is in the seventh character position. I want to use that as an indicator to mark the start of a new question. In the Question Number line, the first three characters together "T1A" are the Question Group. The last part of the T1A*01* is the question number within that group.
So, as you can see I will also need to get the actual question text line and the answer lines as well. Also typically after the four Answer lines is the Question Terminator indicated by "~~". I don't know how I would be able to do this for all the questions in the text file. Do I keep adding them to an array String? How would I access this information from the file and add it to a database. This is very confusing for me and the way I feel I could learn how this works is by seeing an example that covers my situation. Here is a link to the text file I'm talking about:http://pastebin.com/3U3uwLHN
Code:
public static void main(String args[]) {
String endOfSyllabus = "~ End of Syllabus";
Path objPath = Paths.get("2014HamTechnician.txt");
String[] restOfTextFile = null;
if (Files.exists(objPath)){
File objFile = objPath.toFile();
try(BufferedReader in = new BufferedReader(
new FileReader(objFile))){
String line = in.readLine();
List<String> linesFile = new LinkedList<>();
while(line != null){
linesFile.add(line);
line = in.readLine();
}
System.out.println(linesFile);
}
catch(IOException e){
System.out.println(e);
}
}
else{
System.out.println(
objPath.toAbsolutePath() + " doesn't exist");
}
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new A19015_Form().setVisible(true);
}
});
}
Reading a text file in Java is straight forward (and there are sure to be other, more creative/efficient ways to do this):
try (BufferedReader reader = new BufferedReader(new FileReader(path))) { //try with resources needs JDK 7
int lineNum = 0;
String readLine;
while ((readLine = reader.readLine()) != null) { //read until end of stream
Skipping an arbitrary amount of lines can be accomplished like this:
if (lineNum == 0) {
lineNum++;
continue;
}
Your real problem is the text to split on. Had you been using CSV you could use String[] nextLine = readLine.split("\t"); to split each line into its respective cells based on tab separation. But your not, so you'll be stuck with reading each line, and than find something to split on.
It seems like you're in control of the text file format. If you are, go to an easier to consume format such as CSV, otherwise you're going to be designing a custom parser for your format.
A bonus to using CSV is it can mirror a database very effectivly. I.e. your CSV header column = database column.
As far as databases go, using JDBC is easy enough, just make sure you use prepared statements to insert your data to prevent against SQL injection:
public Connection connectToDatabase(){
String url = "jdbc:postgresql://url";
return DriverManager.getConnection(url);
}
Connection conn = connectToDatabase();
PreparedStatement pstInsert = conn.prepareStatement(cInsert);
pstInsert.setTimestamp(1, fromTS1);
pstInsert.setString(2, nextLine[1]);
pstInsert.execute();
pstInsert.close();
conn.close();
--Edit--
I didn't see your pastebin earlier on. It doesn't appear that you're in charge of the file format, so you're going to need to split on spaces ( each word ) and rely on regular expressions to determine if this is a question or not. Fortunately it seems the file is fairly consistent so you should be able to do this without too much problem.
--Edit 2--
As a possible solution you can try this untested code:
try{
BufferedReader reader = new BufferedReader(new FileReader("file.txt")); //try with resources needs JDK 7
boolean doRegex = false;
String readLine;
while ((readLine = reader.readLine()) != null) { //read until end of stream
if(readLine.startsWith("~~ End of Syllabus")){
doRegex = true;
continue; //immediately goto the next iteration
}
if(doRegex){
String[] line = readLine.split(" "); //split on spaces
if(line[0].matches("your regex here")){
//answer should be line[1]
//do logic with your answer here
}
}
}
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
public static void main(String args[])
{
try
{
File file = new File("input.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = "000000", oldtext = "414141";
while((line = reader.readLine()) != null)
{
oldtext += line + "\r\n";
}
reader.close();
// replace a word in a file
//String newtext = oldtext.replaceAll("drink", "Love");
//To replace a line in a file
String newtext = oldtext.replaceAll("This is test string 20000", "blah blah blah");
FileWriter writer = new FileWriter("input.txt");
writer.write(newtext);writer.close();
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
A couple suggestions on your sample code:
Have the user pass in old and new on the command line (i.e., args[0] and args1).
If it's sufficient to do this a line at a time, it's going to be much more efficient to read a line, replace old -> new, then stream it out.
Also check out StringUtils and IOUtils, which may make your life easier in this case.
Easiest is the String.replace(oldstring, newstring), or String.replaceAll(regex, newString) function, you can just read the one file and write the replacement into a new file (or do it line by line if you're concerned about file size).
After reading your last comment - that's a totally different story... the preferred solution would be to parse the css file into an object model (like DOM), apply the changes there and serialize the model to css afterwards. It's much easier to find all color attributes in DOM and change them compared to doing the same with search and replace.
I've found some CSS parser in the wild wild web, but none of them looked like being capable of writing CSS files.
If you wanted to replace the color names with search and replace, you'd search for 'color:<colorname>' and replace it with 'color:<youHexColorValue>'. You may have to do the same for 'color:"<colorname>"', because the color name can be set in double quotes (another argument for using a CSS parser..)
String.replaceAll() is the easiest way to do it. Just read the complete CSS file into one String, replace all as suggested above and write the new String to the same (or a temporary) file (first).