Find String in a text file - regex

I try to find a specific String in a Text File.
The file looks like this:
2, 1, 'Ausbau der techn. Anlagen'
2, 2, 'Extension des installations techniques'
2, 3, 'Estensione delle istallazioni tecniche'
I try to find the text between the '' signs.
//Will be set automaticly after implementation.
int project = 2
int languageInteger = 1
String findings = new File(usedPath)?.eachLine {
it.substring((project+ ", " + languageInteger + ", "))
}
This doesn't work. I've also tried with FindAll Closure or find. But I make some mistakes.
What should I do to find the text?

I found a Solution.
It will not be the best, but it works.
new File(usedPath)?.eachLine {
if(it?.toString()?.startsWith(project+ ", " + languageInteger + ", ")){
findings = it?.toString()?.split(project+ ", " + languageInteger + ", ")?.getAt(1)
}
}

Related

Why is string.find_first_of behaving this way?

I am trying to make a (assembly) parser which uses a string as a guide for how to cut the text to get the tokens I want.
string s = "$t4,";
string guide = "$!,$!,$!";
int i = 1;
string test =s.substr(0, s.find_first_of(" ,.\t"+to_string(guide[i+1]) ));
cout << test << "\n";
if s = "$t4" then test = "$t"
what I am expecting it to do is test to be "$t4", this works for every other $tX except for specifically the number 4 even though it's not in the (" ,.\t"+to_string(guide[i+1])) string
s.find_first_of(" ,.\t" + std::to_string(guide[i + 1]))
Assuming ASCII, that string will be:
,.\t44
44 is the ASCII value of the , in guide[i + 1].
The first character in "$t4," that it'll find is 4 at position 2, and you then create a substring from 0 and length 2, that is $t.

Accessing data required out of for loop in python and store the data at specific location

I am using a for loop for getting data from the user in command prompt using python 2.7. Then storing the data in a text file in certain format. I am looking for a method to get the data from the user and store it in a list and use it where required.
for Input_Number in range(Number_Of_Inputs):
Input_Number = Input_Number+1
GUI_Parameter = str(raw_input("Please enter input parameter " + str(Input_Number) + " :"))
GUI_Parameter_Name = str(raw_input("Enter the GUI name for the parameter " + str(Input_Number) + " :"))
Store_GUI_Parameter(Opened_File, GUI_Parameter, GUI_Parameter_Name)
I would like to use this data to store it in a specific location in a text file according to required syntax. The above code stores the data in the text file. But the problem is it doesn't store it at the required place.
def Store_GUI_Parameter(Opened_File, GUI_Parameter, GUI_Parameter_Name):
GUI_Description = "| " + '"'+ GUI_Parameter_Name + '"' + " |$" + GUI_Parameter.title() + " |"
Write_Data(Opened_File, GUI_Description)
print "GUI parameters written to NDF file"
return
The data storage is done using the above function...
I tried this, but unfortunately this also is not working
GUI_Parameter= []
GUI_Parameter_Name = []
for Input_Number in range(Number_Of_Inputs):
Input_Number = Input_Number+1
GUI_Parameter[Input_Number] = str(raw_input("Please enter input parameter " + str(Input_Number) + " :"))
GUI_Parameter_Name[Input_Number] = str(raw_input("Enter the GUI name for the parameter " + str(Input_Number) + " :"))
Using it outside the loop in the same function...
GUI_Description(Opened_File, GUI_Parameter_Name[Input_Number], GUI_Parameter[Input_Number])
The function implementation:
def GUI_Description(Opened_File, GUI_Parameter_Name[Input_Number], GUI_Parameter[Input_Number]):
Iteration = 0
while Iteration < Input_Number:
Iteration += 1
GUI_Description = "| " + '"'+ GUI_Parameter_Name[Input_Number] + '"' + " |$" + GUI_Parameter[Input_Number].title() + " |"
Write_Data(Opened_File, GUI_Description)
print "GUI parameters written to NDF file"
return
But it shows syntax error at the def GUI_Description
C:\Users\padmanab\Desktop>python CtoN.py File "CtoN.py", line 173
def GUI_Description(Opened_File, GUI_Parameter_Name[Input_Number], GUI_Parameter[Input_Number]):
^ SyntaxError: invalid syntax
The syntax error in the function GUI_Description is caused by your input arguments. 'GUI_Parameter_Name[Input_Number]' is not a valid input argument. Since your function requires both 'GUI_Parameter_Name' and 'Input_Number' they should be separate input arguments. The code snippet below would solve this syntax error:
def GUI_Description(Opened_File, Input_Number, GUI_Parameter_Name, GUI_Parameter):
...
The code below will give an 'index out of range' error since the lists 'GUI_Parameter' and 'GUI_Parameter_Name' have zero length.
GUI_Parameter= []
GUI_Parameter_Name = []
Number_Of_Inputs = 1
for Input_Number in range(Number_Of_Inputs):
Input_Number = Input_Number+1
GUI_Parameter[Input_Number] = str(raw_input("Please enter input parameter " + str(Input_Number) + " :"))
GUI_Parameter_Name[Input_Number] = str(raw_input("Enter the GUI name for the parameter " + str(Input_Number) + " :"))
If you want to add items to the arrays you should append them:
GUI_Parameter.append(raw_input())

Findind more than one word in a file and then extracting the values present after those words?

Note: I asked a similar question but that was put "on hold" because i didn't provide my code (i guess). Now i have written my code also but i am facing some other problem.
From my .bench file, i have to read the values written in brakects () which i managed to do. But the problem is that i have read the values in brakets after INPUT, OUTPUT, NAND.
.bench file
INPUT(1)
INPUT(2)
INPUT(3)
INPUT(6)
INPUT(7)
OUTPUT(22)
OUTPUT(23)
10 = NAND(1, 3)
11 = NAND(3, 6)
16 = NAND(2, 11)
19 = NAND(11, 7)
22 = NAND(10, 16)
23 = NAND(16, 19)
So far, i have written the code to find the values inside brackets after INPUT, OUTPUT, and NAND but as it can be seen that i am repeating the similar lines of code again ana again. So, how can i generalize the same code to find vales after OUTPUT, NAND etc.
int Circuit::readBenchFile(string filename) //read the benchfile and generate inputs, outputs and gates accordingly
{
//Reading the .bench file
ifstream input_file;
char * S = new char[filename.length() + 1];
std::strcpy(S,filename.c_str());
input_file.open(S);
if(input_file.fail())
{
cout << "Failed to open Bench file.\n";
return 1;
}
///////
string line;
string guard_str("#");
string input_str ("INPUT"), output_str ("OUTPUT"), nand_str("NAND");
while (getline( input_file, line ))
{
std::size_t guard_found = line.find(guard_str);
if (guard_found ==std::string::npos)
{
///Input
std::size_t found = line.find(input_str);
if (found!=std::string::npos)
{
found = line.find_first_of('(', found + 1);
//Getting our input name and printing it.
string out = line.substr( found + 1, ( line.find_first_of(')', found) - found - 1) );
std::cout << out << std::endl;
}
///Output
std::size_t found1 = line.find(output_str);
if (found1!=std::string::npos)
{
found1 = line.find_first_of('(', found1 + 1);
//Getting our input name and printing it.
string out = line.substr( found1 + 1, ( line.find_first_of(')', found1) - found1 - 1) );
std::cout << out << std::endl;
}
///NAND
std::size_t found_2 = line.find(nand_str);
if (found_2!=std::string::npos)
{
found_2 = line.find_first_of('(', found_2 + 1);
//find first input
string first_input = line.substr( found_2 + 1, ( line.find_first_of(',', found_2) - found_2 - 1) );
//Second input
found_2 = line.find_first_of(',', found_2 + 2);
string second_input = line.substr( found_2 + 1, ( line.find_first_of(')', found_2) - found_2 - 1) );
cout<<"\nInputs to NAND gate are: "<<( first_input + string(" & ") + second_input );
}
}
}
}
I guess the best way to do it is to use regular expressions. Good option is the Boost Regex library to do that: http://www.boost.org/doc/libs/1_55_0/libs/regex/doc/html/index.html.
If you are not familiar with regular expressions, here is the great page that will get you started very quickly: http://www.regular-expressions.info/. The first paragraph on the main page will give you the idea.
In short: regular expressions make it possible to quickly find patterns in text. You can quickly build a regular expression and the function depending on it, that would return true if any of the words you are looking for is found.
Well if you are looking for genericity I would suggest using boost::split.
vector<string> result;
vector<string> value2;
vector<string> nand_case;
boost::split(result , myline, boost::is_any_of("("));
boost::split(value2, result[1], boost::is_any_of(")"));
if (result[0].find("NAND") != string::pos)
boost::split(nand_case, value2[0], boost::is_any_of(",");
will give you for INPUT(23):
result[0] : INPUT
result[1] : 23)
value2[0] : 23
will give you for OUTPUT(18):
result[0] : OUTPUT
result[1] : 18)
value2[0] : 18
will give you for 23 = NAND(16, 19):
result[0] : 23 = NAND
result[1] : 16, 19)
value2[0] : 16, 19
nand_case[0] : 16
nand_case[1] : 19
Hope I understood correctly and this can help.

Sublime Snippet Regex Replacement

I've recently been creating quite a few Sublime Text 3 plugins/snippets/etc. to automate repetitive tasks. The current one I am stuck on uses regex in a snippet to get my default skeleton for a new function.
Ideally, I would like the snippet would generate something similar to:
// Multiple Args (one arg would obviously look like (..." + "a: " + a + ")");)
function Foo(a, b, c)
{
Log.AppendFolder("Foo(" + "a: " + a + ", b: " + b + ", c: " + c + ")");
//body
Log.PopLogFolder();
}
// Zero Args
function Foo()
{
Log.AppendFolder("Foo()");
//body
Log.PopLogFolder();
}
So far, I can get it formatted with 1 argument or many arguments, not all possible combos (zero, one, many).
The outline is current this, I just need to figure out the second ${2} with regex:
<snippet>
<content><![CDATA[
function ${1:function_name}(${2:arguments})
{
Log.AppendFolder("$1(" + ${2/(?#stuck here)//} + ")");
${3://body}
Log.PopLogFolder();
}$0]]></content>
<tabTrigger>fun</tabTrigger>
<scope>source.js</scope>
<description>Function Template</description>
</snippet>
One Arg:
"$1(" + ${2/^([A-z0-9_-]*),?.*/"\1\: " + \1 + /}");"
Many Args (with 1 arg, this shows "a: " + a + a):
"$1(" + ${2/^([A-z0-9_-]*),?(.*)/"\1\: " + \1 + /}${2/([A-z0-9_-]*)(?:, *([A-z0-9_-]*))/"$2\: " + $2 + /g}");"
One method worked by had an extra + "" + in there, which I'd like to avoid:
${2/([A-z_0-9]+)((?:, ?)?)/"\1\: " + \1 + "\2" + /g}
I've tried a conditional look-ahead based on commas, but that gets messed up >1 arg, probably due to my lack of understanding of them:
${2/(?(?!,)^([A-z0-9_-]*)$|([A-z0-9_-]*), *)/"\1\: " + \1/g}
I could easily do this via a normal plugin (this is easy programmatically), but ideally this can remain a snippet/code-completion since I can just override the JS "fun" code-completion.
What am I missing to accomplish this (or is it simply the wrong avenue - if that's the case, I'd still like to know to learn more about regex)?
Finally figured this out, there is a conditional replacement option:
?n:then:else
So the final format looks like:
<snippet>
<content><![CDATA[
function ${1:function_name}(${2:args})
{
Log.AppendFolder("$1(${2/.+/" + /}${2/([A-z_0-9-]+) *(,)? */"$1\: " + $1 ?2: + "$2 " + :+ /g}${2/.+/"/})");
${3:// body...}
Log.PopLogFolder();
}$0]]></content>
<tabTrigger>fun</tabTrigger>
<scope>source.js</scope>
<description>Function</description>
</snippet>
Which will give the desired result:
function function_name()
{
Log.AppendFolder("function_name()");
// body...
Log.PopLogFolder();
}
function function_name(a)
{
Log.AppendFolder("function_name(" + "a: " + a + ")");
// body...
Log.PopLogFolder();
}
function function_name(a, b)
{
Log.AppendFolder("function_name(" + "a: " + a + ", " + "b: " + b + ")");
// body...
Log.PopLogFolder();
}

Parsing sectioned file with augeas

I am trying to create a module for parsing vim files which are sectioned in a specific manner. A sample file:
" My section {
set nocompatible " be iMproved
set encoding=utf-8
" }
" vim: set foldmarker={,} foldlevel=0 foldmethod=marker:
While writing the module, I've got stuck at this point:
module Vimrc =
autoload xfm
let section = del "\" " "\" " . key /[^\n]+/ . del "\n" "\n" . store /.*/ . del "\" " "\" "
let lns = [ section . del "\n" "\n" ] *
let filter = (incl "*.vim")
let xfm = transform lns filter
I'm aware that there are some other mistakes, but it complains about the regex key /[^\n]+/, saying:
/tmp/aug/vimrc.aug:3.36-.48:exception: The key regexp /[^ ]+/ matches
a '/'
I do not understand what the / character has got to do with this.
As the error says, your key regexp matches a slash, which is illegal since / is used as a level separator in the tree.
If your section names can contain slashes, you need to store them as a node value, not label, so instead of:
{ "My section"
{ "set" = "nocompatible" { "#comment" = "be iMproved" } } }
you'll have to do:
{ "section" = "My section"
{ "set" = "nocompatible" { "#comment" = "be iMproved" } } }