It is very weird, and I don't have any idea what is the issue!
I have a very big string (length=648745), and I don't know if its length can make this issue, but I'm trying to find some parameters inside it, and push them to an array, like this:
push(#items_ids, [$2, $3]) while ($all_items_list =~ /itemID&(id|num)=([\d]*)\">\#([\d]*)/g);
It doesn't work, it returns an empty array at the end. I thought may be my RegEx is not right, but when I run this code:
while ($all_items_list =~ /itemID&(id|num)=([\d]*)\">\#([\d]*)/){
print "\nItemID=$2 Identity=$3\n";die;
}
it finds the first occurrence, when I put "g" at the end of ReEx it can't find it any more...
I know I'm missing something here, Please help me, this is not a hard part of my script and I'm stuck, :( ...
Thanks in advance for your help.
In scalar context, m/.../g starts looking after where a previous successful m/.../g left off. I would suggest resetting the search-position right before the loop:
pos($all_items_list) = undef;
push(#items_ids, [$2, $3]) while ($all_items_list =~ /itemID&(id|num)=([\d]*)\">\#([\d]*)/g);
and seeing if that helps. (See http://perldoc.perl.org/functions/pos.html.)
Related
Having trouble with a script right now.
Trying to filter out portions of a file and put them into a scalar. Here is the code.
#value = (grep {m/(III[ABC])/g and m//g }<$fh>)
print #value;
#value = (grep { m/[012]iii/g}(<$fh>));
print #value;
When I run the first grep , the values appear in the print statment. But when I run the second grep. The 2nd print statement doesnt print anything. Does adding a second grep, cancel out the effectiveness of the first grep ?
I know that first and second grep work because even when I commented out the first grep. The second grep function worked.
All I really want to do, is filter out information, for multiple different individual arrays. I am really confused as to how to fix this problem, since I am planning on adding more grep's to the script.
The first read on <$fh> gets to the end of the file. Then the second invocation has nothing to read. Thus if you comment out the first one this doesn't happen and the second one works.
The code below adds to the same array. Change to the commented out code if needed. The regex is simplified, since it requires a comment while it doesn't affect the actual question. Please put it back the way it was, if that was what you really meant.
You can either rewind the filehandle after all lines have been read
my #vals = grep { /III[ABC]/ } <$fh>;
seek $fh, 0, 0;
# ready for reading again from the beginning
push #vals, grep { /[012]iii/ } <$fh>;
#or: my #vals_2 = grep { /[012]iii/ } <$fh>;
Or you can read all lines into an array that you can then process repeatedly.
my #original = <$fh>;
my #vals = grep { /III[ABC]/ } #original;
push #vals, grep { m/[012]iii/ } #original;
# or assign to a different array
If you don't need to store these results in such order it would be far more efficient to read the file line by line, and process and add as you go.
Update
I simplified the originally posted regex in order to focus on the question at hand, since the exact condition inside the block has no bearing on it. See the Note below. Thanks to ikegami for bringing it up and for explaining that // "repeats the last successful query".
The m//g is tricky and I removed it.
grep checks a condition and passes a line through if the condition evaluates true. In such scalar context /.../g modifier has effects which are a very different story, removed.
For the same reason as above, the capturing () is unneeded (excessive).
Cleaning up the syntax helps readability here, removed m/.
Note on regex
In scalar context /.../g modifier does the following, per perlrequick:
successive matches against a string will have //g jump from match to match
The empty string pattern m//g also has effects which are far from obvious, stated above.
Taken together these produce non-trivial results in my tests and need mental tracing to understand. I removed them from the code here since leaving them begs a question on whether they are intended trickery or subtle bugs, thus distracting from the actual question -- which they do not affect at all.
I don't know what you think the g modifier does, but it makes no sense here.
I don't know what you think // (a match with an empty pattern) does, but it makes no sense here.
In list context, <$fh> returns all remaining lines in the file. It returns nothing the second time you evaluate it since since you've already reached the end of the file the first time you evaluated it.
Fix:
my #lines = <$fh>;
my #values1 = grep { /III[ABC]/ && /.../ } #lines;
my #values2 = grep { /[012]iii/ } #lines;
Of course, substitute ... for what you meant to use there.
I am trying to search a text file that will return a result if more than one word is found in that line. I don't see this explained in the documentation and I have tried various loops with no success.
What I would like to do is something similar to this:
$read(name.txt, s, word1|word2|word3)
or even something like this:
$read(name.txt, w, word1*|*word2*|*word3)
I don't know RegEx that well so I'm assuming this can be done with that but I don't know how to do that.
The documentation in the client self is good but I also recommend this site: http://en.wikichip.org/wiki/mirc. And with your problem there is a nice article : http://en.wikichip.org/wiki/mirc/text_files
All the info is taken from there. So credits to wikichip.
alias testForString {
while ($read(file.txt, nw, *test*, $calc($readn + 1))) {
var %line = $v1
; you can add your own words in the regex, seperate them with a pipe (|)
noop $regex(%line,/(word1|word2|word3|test)/))
echo -a Amount of results: $regml(0)
}
}
$readn is an identifier that returns the line that $read() matched. It is used to start searching for the pattern on the next line. Which is in this case test.
In the code above, $readn starts at 0. We use $calc() to start at line 1. Every match $read() will start searching on the next line. When no more matches are after the line specified $read will return $null - terminating the loop.
The w switch is used to use a wildcard in your search
The n switch prevents evaluating the text it reads as if it was mSL code. In almost EVERY case you must use the n switch. Except if you really need it. Improper use of the $read() identifier without the 'n' switch could leave your script highly vulnerable.
The result is stored in a variable named %line to use it later in case you need it.
After that we use a noop to execute a regex to match your needs. In this case you can use $regml(0) to find the amount of matches which are specified in your regex search. Using an if-statement you can see if there are two or more matches.
Hope you find this helpful, if there's anything unclear, I will try to explain it better.
EDIT
#cp022
I can't comment, so I'll post my comment here, so how does that help in any way to read content from a text file?
I want to read a number of lines from a for loop and split them.
After that i want to do a replace on A SINGLE array element.
my #fs = split(';', $line);
$fs[0] =~ s/\"//g;
This doesnt work however. The line
$fs[0] =~ s/\"//g;
returns a compiler error.
Is there a better way to do this?
Change the line with split to
my #fs = split(/;/, $line);
because split takes a regex as its first operand.
I suspect the parse error you are seeing is due to an error somewhere else because the syntax of the code in your question is correct.
In general, always fix the first error diagnosed by the parser. Good parsers try to recover so as to report as many errors as possible, but this process is not always reliable. What is the exact text of the error you are seeing?
Anyone have any idea why this won't give me back anything?
findNoCase("flashvars.ID = ''",result.FileContent)
I know that flashvars.ID = '' is in the result, as I dump it out and can see it. When I do just...
findNoCase("flashvars.ID",result.FileContent)
It finds it! I could probably do a bunch of crap with len() mid() etc. to find out if the value of flashvars.ID is empty, but I just want to know why the first findNoCase doesn't work!
Probably a whitespace issue. Give this a shot:
#refindNoCase("flashvars\.ID\s*.=\s*.''",content)#
I have a block of codes with timestamp in front of each line like this:
12/02/2010 12:20:12 function myFun()
12/02/2010 12:20:13 {....
The first column is a date time value. I would like to comment them out by using Vim, thus:
/*12/02/2010 12:20:12*/ function myFun()
/*12/02/2010 12:20:13*/ {....
I tried to search for date first:
/\d\d\/\d\d\/\d\d\d\d \d\d:\d\d:\d\d
I got all the timestamps marked correctly. However When I tried to replace them by the command:
%s/\d\d\/\d\d\/\d\d\d\d \d\d:\d\d:\d\d/\/*\d\d\/\d\d\/\d\d\d\d \d\d:\d\d:\d\d*\//
I got the following result:
/*dd/dd/dddd dd:dd:dd*/ function myFun()
/*dd/dd/dddd dd:dd:dd*/ {....
I think I need to name the search part and put them back in the replace part. How I can do it?
I suppose I would just do something like:
:%s-^../../.... ..:..:..-/* & */-
I would actually not us a regex to do this. It takes too long to enter the correct formatting. I would instead use a Visual Block. The sequence works out to be something like this.
<C-V>}I/* <ESC>
3f\s
<C-V>I */
I love regex, and don't want to knock the regex solutions, but find when doing things with pre-formatted blocks, that this is easier, and requires less of a diversion from the real task, which isn't figuring out how to write a regex.
%s/\d\d\/\d\d\/\d\d\d\d \d\d:\d\d:\d\d/\/*&*\//
:%s/^\([0-9/]* [0-9:]* \)\(.*\)/\/*\1*\/ \2/