Guy_

regex 'lazy' eye-opener needed

4 posts in this topic

#1 ·  Posted (edited)

I could use a lesson in laziness... ;)

I sometimes come across this problem where I think I need to use regex 'lazy' and the stuff I'm trying doesn't work, cos I need an eye-opener example for one of my typical problems...

As an example a string of text where I *only* want the red spaces selected (or have a usable $1 and $2) after each piece of "quoted text" longer than 6 characters:

"12345!" Txt "12345!" Txt "123456789!" Txt "12345!" Txt "12345!" Txt "12345678!" Txt

The problem with what I'm trying is that it seems greedy and the selection doesn't stop at the first quote character (going backwards)...
I try '(?U)' and other stuff, but not seeing the light yet...

This is *not* what I want. I want the "12345!" instances ignored... (BTW: don't use '\d', cos it could be anything inside the quotes)
6HUKmRs.png

TIA :)

Edited by Guy_

Share this post


Link to post
Share on other sites



#3 ·  Posted (edited)

Can you try this ?

Yes, I got that to work for my purposes :) It may have a tiny mistake (or not) with the quotes, that I seem to have corrected.
I also got the impression that there are two types of typographers quotes that look exactly alike in some fonts and therefore I had to experiment a bit...

So it seems it had nothing to do with 'laziness' and you used another technique (with help of the exclusions, is my guess.)
I needed to understand that better too, so that will help me many times.

BTW: My intention was to double up the spaces behind the longer quotes, so I can now replace with "$1 "

Thanks!!

Edited by Guy_

Share this post


Link to post
Share on other sites

Don't use lazy, use not. For example to get stuff between quotes use:

"[^"]+"

This means: Match a quote followed by anything that is not a quote a number of times followed by a quote.

Share this post


Link to post
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

  • Similar Content

    • Trong
      By Trong
      Hi,
      I need help string RegEx to get string from CREATE to GO
      #include <StringConstants.au3> ;~ Global $fileSQL1 = @ScriptDir & "\fileSQL1.sql" ;~ Global $fileSQL2 = @ScriptDir & "\fileSQL2.sql" Global $tmpSQLfile = @TempDir & "\tmpFile.sql" OnAutoItExitRegister("_OnExit") _SetTMPsql() If Not FileExists($tmpSQLfile) Then OnAutoItExitUnRegister("_OnExit") Exit MsgBox(48, "/!\", "File: " & $tmpSQLfile & @CRLF & " is not Exists!", 3) EndIf Global $ContentSQLfile = FileRead($tmpSQLfile) _Start() Func _Start() Local $aArray, $iOffset = 1, $stringRegExp = '(?i)CREATE(.*?)GO' While 1 $aArray = StringRegExp($ContentSQLfile, $stringRegExp, $STR_REGEXPARRAYMATCH, $iOffset) If @error Then MsgBox(48, "StringRegExp Error " & @error, "+> StringRegExp: " & $stringRegExp & @CRLF & @CRLF & "=> With STRING:" & @CRLF & @CRLF & $ContentSQLfile) ExitLoop EndIf $iOffset = @extended For $i = 0 To UBound($aArray) - 1 MsgBox(0, "RegExp Test with Option 1 - " & $i, $aArray[$i]) Next WEnd EndFunc ;==>_Start Func _SetTMPsql() Local $tmpSQLContent = "" $tmpSQLContent &= "USE [Master]" & @CRLF $tmpSQLContent &= "GO" & @CRLF $tmpSQLContent &= "" & @CRLF $tmpSQLContent &= "CREATE DATABASE [Sales] ON PRIMARY " & @CRLF $tmpSQLContent &= "( NAME = N’Sales’, FILENAME = N’\FSASQLDBSales.mdf’ , " & @CRLF $tmpSQLContent &= " SIZE = 2GB , MAXSIZE = 8GB, FILEGROWTH = 1GB )" & @CRLF $tmpSQLContent &= "LOG ON " & @CRLF $tmpSQLContent &= "( NAME = N’Sales_log’, FILENAME = N’\FSASQLDBSales_log.ldf’ , " & @CRLF $tmpSQLContent &= " SIZE = 1GB , MAXSIZE = 2GB , FILEGROWTH = 10%)" & @CRLF $tmpSQLContent &= "GO" & @CRLF $tmpSQLContent &= "" & @CRLF $tmpSQLContent &= "USE [Sales]" & @CRLF $tmpSQLContent &= "GO" & @CRLF $tmpSQLContent &= "" & @CRLF $tmpSQLContent &= "-- Table Product" & @CRLF $tmpSQLContent &= "CREATE TABLE [dbo].[Product]" & @CRLF $tmpSQLContent &= "(" & @CRLF $tmpSQLContent &= " [ProductId] [uniqueidentifier] DEFAULT NEWID() NOT NULL," & @CRLF $tmpSQLContent &= " [ProductName] [nchar](50) NULL," & @CRLF $tmpSQLContent &= " [ProductDescription] [nchar](3000) NULL," & @CRLF $tmpSQLContent &= " [ProductPrice] MONEY NULL" & @CRLF $tmpSQLContent &= ") ON [PRIMARY]" & @CRLF $tmpSQLContent &= "GO" & @CRLF $tmpSQLContent &= "" & @CRLF $tmpSQLContent &= "-- Table Sales" & @CRLF $tmpSQLContent &= "CREATE TABLE [dbo].[Sales]" & @CRLF $tmpSQLContent &= "( " & @CRLF $tmpSQLContent &= " [SaleId] [uniqueidentifier] DEFAULT NEWID() NOT NULL," & @CRLF $tmpSQLContent &= " [SaleName] [nchar](50) NULL," & @CRLF $tmpSQLContent &= " [SaleInfo] [nchar](3000) NULL," & @CRLF $tmpSQLContent &= " [SaleMoney] MONEY NULL" & @CRLF $tmpSQLContent &= ") ON [PRIMARY]" & @CRLF $tmpSQLContent &= "GO" & @CRLF $tmpSQLContent &= "" & @CRLF $tmpSQLContent &= "SET ANSI_NULLS ON" & @CRLF $tmpSQLContent &= "GO" & @CRLF $tmpSQLContent &= "SET QUOTED_IDENTIFIER ON" & @CRLF $tmpSQLContent &= "GO" & @CRLF $tmpSQLContent &= "" & @CRLF $tmpSQLContent &= "-- The End" & @CRLF Local $hOpen = FileOpen($tmpSQLfile, 2 + 8 + 128) FileWrite($hOpen, $tmpSQLContent) Return FileClose($hOpen) EndFunc ;==>_SetTMPsql Func _OnExit() Exit FileDelete($tmpSQLfile) EndFunc ;==>_OnExit  
      mikell
       
    • MuffinMan
      By MuffinMan
      I am trying to rebuild an old single signon script that has been giving us a bit of trouble lately.  I didn't write it and it was written in another script language.  If the target program is already open it will have the current user's last name as part of the window text, which I am trying to compare against the user name to see if I should just WinActivate or Process Close and start the program over.  I will be provided the username like "jones", or "smith" and the title check works fine for last names (with no spaces), but if the last name DOES contains spaces, say "Nom De Plume", then all I will be given as a username is "nomdeplume".  Is there any way (via a regex maybe) that I can still check the text on the screen and somehow ?  I have been reading about the Advanced (4) mode of WinTitleMatchMode, but it is over my head.  Any help is appreciated.  Here is a small reproducer script:
      Opt("WinTitleMatchMode", -1) Run("Notepad") WinWait("[CLASS:Notepad]", "", 10) Send ("Smith" & @CRLF & "Jones" & @CRLF & "Nom De Plume" & @CRLF) If WinExists("[CLASS:Notepad]", "jones") Then MsgBox(0,"FOUND","Found Jones") EndIf If WinExists("[CLASS:Notepad]", "nomdeplume") Then MsgBox(0,"FOUND","Found Nom De Plume") EndIf  
    • rcmaehl
      By rcmaehl
      Currently I have
      Switch StringLen($Serial) Case 0 Return "Please Enter a Serial #" Case 1 To 6 Return "UNKNOWN or INCORRECT" Case 7 Select Case StringLeft($Serial, 2) = "79" $Valid = "Device 1" Case StringLeft($Serial, 3) = "350" $Valid = "Device 2" Case StringRegExp($Serial, "72[HR](.*)") ; Match 72H and 72R $Valid = "Device 3" Case Else $Valid = "UNKNOWN or INCORRECT" EndSelect Case 8 Select Case StringRegExp($Serial, "\d[A-Z](.*)") ; Match a Digit (0-9), then a letter $Valid = "Device 4 short format" Case Else $Valid = "UNKNOWN or INCORRECT" EndSelect EndSwitch Which I'm using to match a number followed by a letter then any number of digits up to a string length of 8 characters.
      However I don't want it to match strings such as 1234A123 only 1D123456
      Is there anyway to do this using a flag or am I limited to having to use StringLeft()?
    • Chiitus
      By Chiitus
      Hello guys, i have a problem in this regex because its not groupping right.
      Look:
      (\d{1,2}\s?[\055|\056|\057|\134]\s?\d{1,2}(\s?[\055|\056|\057|\134]\s?\d{2,4})?) It checks for day or dayday, month or monthmonth, yearyear or yearyearyear+year.
      separated with or without space and the characters "\/.-"
      But, a problem! I tried to regex the date with or without the "separator + year" Eg: 05/05 or 05/05/05, but when i have 05/05/05, regex are separating 05/05 and /05
      Iam using group "()" wrong?
      Need help here
      Thx adv!
      ~~EDIT:
      Script used: (from autoitscript.com/forum/topic/129697-split-string-by-regular-expression/#comment-901335)
      #include <Array.au3> Local $sString = ClipGet() ; Extract the delimiters $aDelim = StringRegExp($sString, '(\d{1,2}\s?[\055|\056|\057|\134]\s?\d{1,2}(\s?[\055|\056|\057|\134]\s?\d{2,4})?)', 3) ; Split the string on the delimiters $aParts = StringSplit(StringRegExpReplace($sString, '(\d{1,2}\s?[\055|\056|\057|\134]\s?\d{1,2}(\s?[\055|\056|\057|\134]\s?\d{2,4})?)', "$<SEPARATOR>$"), "$<SEPARATOR>$", 3) ; Add the delimter to the start of the part For $i = 0 To UBound($aParts) - 1 ;$aParts[$i + 1] = $aDelim[$i] & $aParts[$i + 1] Next ; Set the count $aParts[0] = UBound($aParts) ; Display the result _ArrayDisplay($aParts) _ArrayDisplay($aDelim) Results in array: (the array parts in all string is ok; but the string delimitator himself is getting separated in every string that have year together)

      String used as test:
      Cheers.
    • TheDcoder
      By TheDcoder
      Hello , I am trying to find the best way to spilt this string:
      :<nick>!<host mask> PRIVMSG <channel/nick> :<message> into an array like this:
      Global Enum $SENT_BY, $HOST_MASK, $SENT_TO, $MESSAGE $aArray[$SENT_BY] = "<nick>" $aArray[$HOST_MASK] = "<host mask>" $aArray[$SENT_TO] = "<channel/nick>" $aArray[$MESSAGE] = "<message>" (Stuff between <> is dynamic)
      I can do that with inefficient code but I think it is possible to do it more efficiently with RegEx
       
      Thanks in Advance! TD
       
      P.S Yeah, that is the raw format of a message received in IRC