Jump to content

How to search only the second StringRegExp Or Second Random String?


Go to solution Solved by mikell,

Recommended Posts

Local $a = StringRegExp(FileRead("database2.txt"), "\},\s*(\d+)", 3)
_ArrayDisplay($a)

 

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

@jchd
What if I want to search only specific number based by category?

Because I want to do StringRegExpReplace later to increase variable amount based on specific category

For example,

I want to:
increase arts & entertainments 10 to be 23

increase biographies & memoirs 10 to be 28

Is there any possibilites to do something like this?
 

$database = StringRegExp($text, 'category":(.*)},\s+(\d+)', 3)

I mean, can I search category": then using (.*) to skip any characters until I found }, then \s+(\d+)

so that I can capture only (\d+)?

Link to comment
Share on other sites

JSON isn't a database. If you're going to routinely handle a significant volume of data, use a real database. SQLite is very easy to use, can handle JSON natively and is well supported by AutoIt.

Else you're going to make your life extra difficult by managing JSON by regexes.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

1 hour ago, HezzelQuartz said:

variable amount based on specific category

Regex can do this

#Include <Array.au3>

$text = FileRead(@ScriptDir & "\" & "database2.txt")
$categories = StringRegExp($text, '(?s)category":[^}]+},\s+\d+', 3)
;_ArrayDisplay($categories)

$arts = 23
$biographies = 28

For $i = 0 to UBound($categories)-1
    If StringInStr($categories[$i], "arts & entertainment") Then
        $new = StringRegExpReplace($categories[$i], '(\d+)$', $arts )
        $text = StringReplace($text, $categories[$i], $new)
    ElseIf StringInStr($categories[$i], "biographies & memoirs") Then
        $new = StringRegExpReplace($categories[$i], '(\d+)$', $biographies )
        $text = StringReplace($text, $categories[$i], $new)
    EndIf
Next
Msgbox(0,"", $text)

But jchd is right, if you plan to manage a big amount of data, or if you have to change more variables - i.e. the number of "Price" or "Discount" , or add/remove a "Discount" line, etc ..... even if all this is still doable using regex it would become more and more complicated

Edited by mikell
Link to comment
Share on other sites

Lookup SQLite UDF in AutotIt Help. Familiarize yourself with SQLite doc found at sqlite.org and JSON functions https://www.sqlite.org/json1.html

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

19 hours ago, HezzelQuartz said:

I really want to learn how to do it via regex

The weather is actually extremely hot and I have to stay confined under my air conditioner, so I played a little :)
Assuming that the format of the "database" file remains unchanged, this should work ...

#Include <Array.au3>

$text = FileRead(@ScriptDir & "\" & "database2.txt")

; change a number
_SetModif($text, "book", "arts & entertainment", "ABCDE", "number", "345")
;Msgbox(0,"1", $text)

; change a price
_SetModif($text, "book", "biographies & memoirs", "FGHIJ", "price", "16525")
;Msgbox(0,"2", $text)

; change a discount value
_SetModif($text, "book", "computers & technology", "UVWXY", "discount", "44")
;Msgbox(0,"3", $text)

; remove a discount line
;_SetModif($text, "book", "arts & entertainment", "ABCDE", "discount", "")
;Msgbox(0,"4a", $text)

; remove all discount lines in arts & entertainment
;_SetModif($text, "book", "arts & entertainment", "", "discount", "")
;Msgbox(0,"4b", $text)

; remove all discount lines in books
_SetModif($text, "book", "", "", "discount", "")
;Msgbox(0,"4c", $text)

; create a discount line
_SetModif($text, "book", "biographies & memoirs", "FGHIJ", "discount", "33")
Msgbox(0,"5", $text)

;---------------------------------------------------------

Func _SetModif(ByRef $text, $name, $category, $title, $item, $value)
    $categories = StringRegExp($text, '"name":[^}]+},\s+\d+', 3)
    ;_ArrayDisplay($categories)
    For $i = 0 to UBound($categories)-1
        If StringRegExp($categories[$i], '"name": "' & $name) and _ 
                        StringRegExp($categories[$i], '"category": "' & $category) and _ 
                        StringRegExp($categories[$i], '"title": "' & $title) Then
            If $item == "number" Then
                $new = StringRegExpReplace($categories[$i], '(\d+)$', $value)
            ElseIf $item == "discount" Then
                If $value = "" Then
                    $new = StringRegExpReplace($categories[$i], '(?i),?\s+"discount"\N+', $value)
                Else
                    If StringInStr($categories[$i], '"discount": "') Then
                        $new = StringRegExpReplace($categories[$i], '(?i)(?<="discount": ")([^"]+)', $value)
                    Else
                        $d = '"Discount": "' & $value & '"'
                        $new = StringRegExpReplace($categories[$i], '(?i)(\h+)"price":\N+\K(\R)', ',$2$1' & $d & '$2')
                    EndIf
                EndIf
            Else
                $new = StringRegExpReplace($categories[$i], '(?i)(?<="' & $item & '": ")([^"]+)', $value)
            EndIf
            $text = StringReplace($text, $categories[$i], $new)
        EndIf
    Next
EndFunc

Edit
I'll try to have a look at SQLite and these json funcs

Edited by mikell
Link to comment
Share on other sites

@HezzelQuartz I always wondered if the category could be duplicated in your database, for example :

  "database": [
    {
      "name": "book",
      "category": "arts & entertainment",
      "title": "ABCDE",
      "Price": "15000",
      "Discount": "10"
    },
    13,
    {
      "name": "book",
      "category": "arts & entertainment",
      "title": "FGHIJ",
      "Price": "20000"
    },
    18,
    { etc...

Link to comment
Share on other sites

@mikell imho I think this database should have its unique key composed by name & category & title.
It won't be long before OP adds a new rule, stipulating that there are other "name lines" in the database (because why is there a name line = book, if there are no other name lines anywhere in the database ?)
So before he presents a database like this, with different "name :" ...

  "database": [
    {
      "name": "book",
      "category": "arts & entertainment",
      "title": "ABCDE",
      "Price": "15000",
      "Discount": "10"
    },
    13,
    {
      "name": "book",
      "category": "arts & entertainment",
      "title": "FGHIJ",
      "Price": "18000"
    },
    18,
    {
      "name": "DVD",
      "category": "arts & entertainment",
      "title": "FGHIJ",
      "Price": "25000",
      "Discount": "10"
    },
    25,
    { etc...

As you wrote, if this database structure is about to change and change again, this will never end, especially the RegEx part of the script which will be more complicated to maintain.
Link to comment
Share on other sites

Also to be valid JSON/JSON5, the whole input must be enclosed in curly braces { <text> }

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

14 hours ago, pixelsearch said:

It won't be long before OP adds a new rule

I edited my previous code. Without knowing the whole requirements it's actually the best I can offer  :)
BTW you're right about "should have its unique key composed by name & category & title"

Edited by mikell
Link to comment
Share on other sites

I've taken the time to create a very basic script to turn the JSON (once correctly enclosed in { and }) into a useable SQLite database, also provided.

You can use a free SQLite manager (I warmly recommend https://www.sqliteexpert.com/) to view, query, edit and otherwise manage the resulting DB.

inventory.zip

Edited by jchd

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

@jchd
Thank you, I will look into it.

=======================================================================================================================================

@Everyone

I think I have last question for this thread

Is there any way I can do StringRegExpReplace to search database, and any string after database until I get last square bracket symbol ']'
I put script below for ilustration
 

#Include <Array.au3>

$text = FileRead(@ScriptDir & "\" & "database.txt")
$textalt = FileRead(@ScriptDir & "\" & "databasealt.txt")
$database = StringRegExp($text, '(?s)database' & '(.*)?' & '  ]', 3)
$databasealt = StringRegExp($textalt, '(?s)database' & '(.*)?' & '  ]', 3)


StringRegExpReplace($text, '(?s)database' & '(.*)?' & '  ]', $databasealt)

FileWrite(@ScriptDir & "\" & "newdatabase.txt", $text)


I want to use StringRegExpReplace to "replace" all the content between   "database": [ and   ] from file "database alt" to file "database"

Let's assume there is string other than database that I don't want to copy, so that I cannot copy all the string, only part of the string

last database.png

last database alt.png

Link to comment
Share on other sites

Your question is not very clear. You could extract the content and replace it, or do the replacement directly

$text = FileRead(@ScriptDir & "\" & "database2.txt")

$extracted = StringRegExpReplace($text, '(?s)(^\h*"database":\N+\R\h+)(.*?)(\R\h*\]$)', "$2")
Msgbox(0,"", $extracted)
$new = StringReplace($text, $extracted, "****")
Msgbox(0,"1", $new)

$new = StringRegExpReplace($text, '(?s)database":\N+\R\h+\K(.*?)(?=\R\h+\]$)', "****")
Msgbox(0,"2", $new)

 

Link to comment
Share on other sites

  • 2 weeks later...

@mikell
Wow, as always, working as I want

Could you please explain, what is
\N+ I don't really understand what is this "Matches any character except a newline sequence regardless of option (?s)"

\R I also don't really understand what is "Matches any unicode newline sequence by default, or the currently active (*BSR) setting.

(?=\R\h+\]$)

I see \N+ and \R in help file but could you explain in another easier explanation for me?

Thank you

Edited by HezzelQuartz
Link to comment
Share on other sites

3 hours ago, HezzelQuartz said:

I see \N+ and \R in help file but could you explain in another easier explanation for me?

Easier ? hmmm I'll try.
You know what a newline sequence is : the thingy at the end of a line of text which leads to ... a new line. In your file, this newline sequence is @CRLF

The help file says :
What \R matches
(*BSR_ANYCRLF) By default \R matches @CRLF, @CR or @LF only.

So in your file, \N+\R means : "one or more chars which are not @CRLF, and the @CRLF"

  :)
Link to comment
Share on other sites

4 hours ago, HezzelQuartz said:

Then, what is
(?=\R\h+\]$)

It's a lookahead, nothing complicated here. It means :
" followed by @crlf, one or more horizontal spaces, a closing bracket, the end of the whole text "

With all these expressions you are learning regex the hard way. I highly suggest that for each new concept you learn, you build yourself some simple examples so you understand clearly how it works and how to use it in more complex expressions  omg.gif.994f4eb4539123a1b39b80d2e6f14263.gif

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...