Jump to content

How to use (?m) in StringRegExp


Recommended Posts

Hi All,

I try to match some words in a file. This file has multiple lines. Every line has one words I want to match. I noted (?m) could be useful for this situation. But tried and failed. Don't know how to use it? please help. Below is an example file, let say I want to match the words like aa11aa in the first column when the second column is OK status.

aa11aa,OK,OK,NO,no access

bb11bb,OK,OK,NO,no access

cc11cc,INCORRECT,OK,NO,no access

Thanks a lot.

Lou

Link to comment
Share on other sites

(?m) is a flag. It allows ^ and $ to match new lines in addition to the beginning and end of line that they originally match (respectively).

However, I don't quite understand what you are trying to do...

First, you speak of files, then you talk of "columns" (:P I'll assume you mean "Row" or in the case of a text file, "Line") and then want to match text in one "column" conditionally as long as there is something else in another "column"

StringRegExp is meant to determine whether or not a string is in a certain format, and/or to pull data from a string that is in a known format. Not to conditionally read from different parts of a file...or whatever you seem to be trying to do with it. :P

Link to comment
Share on other sites

(?m) is a flag. It allows ^ and $ to match new lines in addition to the beginning and end of line that they originally match (respectively).

However, I don't quite understand what you are trying to do...

First, you speak of files, then you talk of "columns" (:P I'll assume you mean "Row" or in the case of a text file, "Line") and then want to match text in one "column" conditionally as long as there is something else in another "column"

StringRegExp is meant to determine whether or not a string is in a certain format, and/or to pull data from a string that is in a known format. Not to conditionally read from different parts of a file...or whatever you seem to be trying to do with it. :P

Thank you Paulie for quick response. I'm trying to match one word in every line in the file. I just found there is FileReadLine function can read every line one time. Then I can match the word in the line and return this word.

But still confused with (?m) option. could you please give me a usage example for this (?m) option? Thank you very much

Lou

Link to comment
Share on other sites

My best attempt at an example

#include <Array.au3>
$String = "Beginning Mid"&@LF&"dle End" ; String with a newline in the middle

$Pattern1 = "(?s)^(.*?)$" 
;Pattern 1:
; Match all characters between the beginng and end of the string (will match entire string) 
$Pattern2 = "(?m)" & $Pattern1
;Pattern 2:
; Match all characters between begging of string OR NEW LINE and End of string OR NEW LINE

$Res1 = StringRegExp($String, $Pattern1,3)
$Res2 = StringRegExp($String, $Pattern2,3)
_ArrayDisplay($Res1,"1")
_ArrayDisplay($Res2,"2")
Edited by Paulie
Link to comment
Share on other sites

  • Moderators

$s_string would be FileRead()

$s_string = FileRead("location\Filename.extension")

#include <array.au3>
Local $a_file, $s_string
$s_string = "aa11aa,OK,OK,NO,no access" & @CRLF
$s_string &= "bb11bb,OK,OK,NO,no access" & @CRLF
$s_string &= "cc11cc,INCORRECT,OK,NO,no access"

Local $a_matches = _MatchValueRow($s_string, "aa11aa", 2, "ok")
_ArrayDisplay($a_matches)

Func _MatchValueRow($s_string, $s_find, $n_row, $s_valuematch, $v_casesensitive = "", $s_delim = ",")
    If Not $v_casesensitive Then
        $v_casesensitive = "(?i)"
    Else
        $v_casesensitive = ""
    EndIf
    
    Local $a_split = StringSplit(StringStripCR($s_string), @LF)
    
    ;Escape the escape chars
    Local $s_pattern_escapechars = "(\.|\||\*|\?|\+|\(|\)|\{|\}|\[|\]|\^|\$|\\)"
    $s_find = StringRegExpReplace($s_find, $s_pattern_escapechars, "\\\1")
    $s_delim = StringRegExpReplace($s_delim, $s_pattern_escapechars, "\\\1")
    $s_valuematch = StringRegExpReplace($s_valuematch, $s_pattern_escapechars, "\\\1")
    
    ;How many delimeters
    Local $n_delimeters = UBound(StringRegExp($a_split[1], "(" & $s_delim & ")", 3))
    
    ;If $n_delimeters = 0 Then Return SetError(1, 0, 0)
    ;If $n_delimeters < ($n_row - 1) Then Return SetError(2, 0, 0)
    
    ;Create pattern
    Local $i, $s_pattern_findvalue = $v_casesensitive & "\A" & $s_find & $s_delim
    If $n_row > 2 Then
        For $i = 3 To $n_row
            $s_pattern_findvalue &= ".+?" & $s_delim
        Next
    EndIf
    
    $s_pattern_findvalue &= $s_valuematch & "(?:\z|" & $s_delim & ")"
    
    ; If the pattern matches, document the column number, and return the array of columns that match
    Local $a_match[$a_split[0] + 1], $i_add, $i_column
    For $i_column = 1 To $a_split[0]
        If StringRegExp($a_split[$i_column], $s_pattern_findvalue) Then
            $i_add += 1
            $a_match[$i_add] = $i_column
        EndIf
    Next
    
    If Not $i_add Then Return SetError(3, 0, 0)
    
    ReDim $a_match[$i_add + 1]
    $a_match[0] = $i_add
    Return $a_match
EndFunc
[0] holds the number of matches found in the file, and from [1] on will be what line/column it was found on.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

Sigh... :P ... only you smoke... only you :o

yeah, but I named the columns and rows wrong :P , I was just trying to get it done on my loading the moving truck break ... had the thought in my head and just went to typing.

Also need to un-comment the two If statements for extra error handling.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

yeah, but I named the columns and rows wrong :P , I was just trying to get it done on my loading the moving truck break ... had the thought in my head and just went to typing.

Also need to un-comment the two If statements for extra error handling.

I'm not sure how you knew what he wanted to do! :P

You should let me borrow your crystal ball once in a while!

Link to comment
Share on other sites

My best attempt at an example

#include <Array.au3>
$String = "Beginning Mid"&@LF&"dle End" ; String with a newline in the middle

$Pattern1 = "(?s)^(.*?)$" 
;Pattern 1:
; Match all characters between the beginng and end of the string (will match entire string) 
$Pattern2 = "(?m)" & $Pattern1
;Pattern 2:
; Match all characters between begging of string OR NEW LINE and End of string OR NEW LINE

$Res1 = StringRegExp($String, $Pattern1,3)
$Res2 = StringRegExp($String, $Pattern2,3)
_ArrayDisplay($Res1,"1")
_ArrayDisplay($Res2,"2")
Thank you very much. I got it.

Lou

Link to comment
Share on other sites

$s_string would be FileRead()

$s_string = FileRead("location\Filename.extension")

#include <array.au3>
Local $a_file, $s_string
$s_string = "aa11aa,OK,OK,NO,no access" & @CRLF
$s_string &= "bb11bb,OK,OK,NO,no access" & @CRLF
$s_string &= "cc11cc,INCORRECT,OK,NO,no access"

Local $a_matches = _MatchValueRow($s_string, "aa11aa", 2, "ok")
_ArrayDisplay($a_matches)

Func _MatchValueRow($s_string, $s_find, $n_row, $s_valuematch, $v_casesensitive = "", $s_delim = ",")
    If Not $v_casesensitive Then
        $v_casesensitive = "(?i)"
    Else
        $v_casesensitive = ""
    EndIf
    
    Local $a_split = StringSplit(StringStripCR($s_string), @LF)
    
    ;Escape the escape chars
    Local $s_pattern_escapechars = "(\.|\||\*|\?|\+|\(|\)|\{|\}|\[|\]|\^|\$|\\)"
    $s_find = StringRegExpReplace($s_find, $s_pattern_escapechars, "\\\1")
    $s_delim = StringRegExpReplace($s_delim, $s_pattern_escapechars, "\\\1")
    $s_valuematch = StringRegExpReplace($s_valuematch, $s_pattern_escapechars, "\\\1")
    
    ;How many delimeters
    Local $n_delimeters = UBound(StringRegExp($a_split[1], "(" & $s_delim & ")", 3))
    
    ;If $n_delimeters = 0 Then Return SetError(1, 0, 0)
    ;If $n_delimeters < ($n_row - 1) Then Return SetError(2, 0, 0)
    
    ;Create pattern
    Local $i, $s_pattern_findvalue = $v_casesensitive & "\A" & $s_find & $s_delim
    If $n_row > 2 Then
        For $i = 3 To $n_row
            $s_pattern_findvalue &= ".+?" & $s_delim
        Next
    EndIf
    
    $s_pattern_findvalue &= $s_valuematch & "(?:\z|" & $s_delim & ")"
    
    ; If the pattern matches, document the column number, and return the array of columns that match
    Local $a_match[$a_split[0] + 1], $i_add, $i_column
    For $i_column = 1 To $a_split[0]
        If StringRegExp($a_split[$i_column], $s_pattern_findvalue) Then
            $i_add += 1
            $a_match[$i_add] = $i_column
        EndIf
    Next
    
    If Not $i_add Then Return SetError(3, 0, 0)
    
    ReDim $a_match[$i_add + 1]
    $a_match[0] = $i_add
    Return $a_match
EndFunc
[0] holds the number of matches found in the file, and from [1] on will be what line/column it was found on.
SmOke_N,

Thank you very much. It's very helpful.

Lou

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...