I have a script which look for the name and search for a match with a another variable.
It's working fine however if the variable 1 is "Name Demo" and variable 2 is "Demo Name" then the script don't find a match.
set nameMatchTXT to ""
if NameOnDevice contains theName then
set nameMatch to theName & " : Name Match"
end if
Is there anyway to change this to find the match whatever the order ?
PS the script is looking for word wild name, and sometime handle dual bit characters which can be a difficulty.
Your request stated:
if the variable 1 is "Name Demo" and variable 2 is "Demo Name" then
the script don't find a match.
This will solve that problem:
set var1 to "Name Demo"
set var2 to "Demo Name"
if (var2 contains (word 1 of var1)) and (var2 contains (word 2 of var1)) then
-- you have a match
display dialog "var1 and var2 match"
else
display dialog "no match"
end if
You will have to have make a separate check for each condition. There are other ways to do it (such as a complex regex), but this is the easiest and most readable.
set nameMatch1 to "Name"
set nameMatch2 to "Demo"
if (NameOnDevice contains nameMatch1) and (NameOnDevice contains nameMatch2) then
set nameMatch to NameOnDevice & " : Name Match"
end if
If you are adding matching criteria, you may eventually add more. Instead of adding more variables, and more conditions, you may want to put all of your words in a list and check against that. In the future, if you need to add more words, you can simply add the word to the list. I've extracted it into a separate sub-routine here for easier reading:
on name_matches(nameOnDevice)
set match_words to {"Name", "Demo"}
repeat with i from 1 to (count match_words)
if nameOnDevice does not contain item i of match_words then
return false
end if
end repeat
return true
end name_matches
if name_matches(nameOnDevice) then
set nameMatch to nameOnDevice & " : Name Match"
end if
Edit after clarification
If you have no control over the matching text (if it comes from an outside source, and is not coded by you), you can split that text into words and use those as the wordlist in the second example. For instance:
on name_matches(nameOnDevice, match_text)
set match_words to words of match_text
repeat with i from 1 to (count match_words)
if nameOnDevice does not contain item i of match_words then
return false
end if
end repeat
return true
end name_matches
if name_matches(nameOnDevice, match_text_from_some_other_source) then
set nameMatch to nameOnDevice & " : Name Match"
end if
Related
I was trying to construct some code to search for text where one word within the text is a particular format or style. For example, I would like to search for the text "Hello world, all is good" but only hit instances where the word "all" is in bold.
I thought about searching for the first few words "Hello world, "; collapsing the selection, searching the next three characters forward for the word "all" in bold; collapsing the selection (if true) then searching the next bit for the words " is good". This would result in identifying the whole phrase with the bold word but it seems really inefficient and not very flexible. Also, to then select the whole sentence, I have to write code to move the selection back to the start and extend the selection forward. Then I need to reset the search to continue forward from that position.
Is there some easy/easier/more elegant way to search for a string where only one word within the string has specific properties like bold? I specifically want the search to ignore instances of the phrase where the relevant word is not in bold.
I have spent a few hours searching google and stackflow and can't find anything on this.
I haven't posted code because I am not very good at writing the code, and I really want to understand if there is a flexible/elegant way of doing what I want. The inflexible root I've explained above is so inflexible I'm reluctant to bother coding something.
Thanks
Jeremy
The method I would use is to search for the string and, if found, then search the string for the word. Here is an example.
Sub Demo()
Dim StringRange As Range
Dim MatchFound As Boolean
With ActiveDocument.Range.Find
' The string to find
.Text = "Hello world, all is good"
' Search the document
Do While .Execute
' Capture the string
Set StringRange = .Parent.Duplicate
With .Parent.Duplicate.Find
' The word to find
.Text = "all"
.Font.Bold = True
' Search the string
If .Execute Then
MatchFound = True
StringRange.Select
If MsgBox("Match found. Continue searching?", vbQuestion + vbYesNo) = vbNo Then
Exit Sub
End If
End If
End With
Loop
If MatchFound Then
MsgBox "Finished searching document", vbInformation
Else
MsgBox "No match found", vbInformation
End If
End With
End Sub
I have a text like this:
"entity"
{
"id" "5040044"
"classname" "weapon_defibrillator_spawn"
"angles" "0 0 0"
"body" "0"
"disableshadows" "0"
"skin" "0"
"solid" "6"
"spawnflags" "3"
"origin" "449.47 5797.25 2856"
editor
{
"color" "0 0 200"
"visgroupshown" "1"
"visgroupautoshown" "1"
"logicalpos" "[-13268 14500]"
}
}
What would regex expression be to select only that part in Notepad++:
editor
{
"color" "0 0 200"
"visgroupshown" "1"
"visgroupautoshown" "1"
"logicalpos" "[-13268 14500]"
}
First word is always "editor", but the number of lines and content in curly brackets may vary.
editor\s*{\s*(?:\"[a-z]*\"\s*\".*\"\s*)*\}
Demo
Also tested it in Notepad++ it works fine
The simplest way to find everything between curly brackets would be \{[^{}]*\} (example 1).
You can prepend editor\s* on it so it limits the search to only that specific entry: editor\s*\{[^{}]*\} (example 2).
However... if any of the keys or value strings within editor {...} contain a { or }, you're going to have edge cases.
You'll need to find double-quoted values and essentially ignore them. This example shows how you would stop before the first double quote within the group, and this example shows how to match up through the first key-value pair.
You essentially want to repeatedly match those key-value pairs until no more remain.
If your keys or values can contain \" within them, such as "help" "this is \"quoted\" text", you need to look for that \ character as well.
If there are nested groups within this group, you'll need to recursively handle those. Most regex (Notepad++ included) don't handle recursion, though, so to get around this, you copy-paste what you have so far inside of the code if it happens to come across more nested { and }. This does not handle more than one level of nesting, though.
TL;DR
For Notepad++, this is a single line regex you could use.
I have a text file that looks like this: screenshot below
http://i.stack.imgur.com/AqKzS.png
Each item has this format:
ID<>Text
~~
ID<>Text
~~
I want to fetch the ID in an INT to be used later. And the Text in a String to be used later.
I looped over the file many times using delimiters "<>" & "~~". However, I fail each time with a different script error.
first I faced difficulties because the file contains a lot of newlines throughout the "Text". Also, the text sometimes contains an English paragraph followed by an Arabic paragraph, as showed in the Screenshot.
The ID as highlighted should be {9031} and the Text should be {N/M06"El Patio.......
......
....
....
....
Arabic Text.....}
Can someone help me with the correct script to loop over this text file and fetch each ID followed by its text to be used in a DataEntry process?
For this purpose I recommend to install Satimage sax 3.7.0
The benefit is to find text with regular expression.
Then you easily filter the text with find text
set theText to read file "HD:Path:to:text.txt" as «class utf8» -- replace the HFS path with the actual path
set theResult to {}
set matches to find text "\\d{1,4}<>.*" in theText with regexp and all occurrences
repeat with aMatch in matches
tell aMatch's matchResult
set end of theResult to {text 1 thru 4, text 7 thru -1}
end tell
end repeat
find text returns a record:
matchLen: length of the match
matchPos: offset of the match (0 is the first character!)
matchResult: the matching string (possibly formatted according to the "using" parameter)
The result of the script in variable theResult is a list of lists containing the id and the text. The text starts after the <> but you might cut more characters.
Edit:
It seems that the regex can't parse this text (or my regex knowledge is too bad).
This is a pure AppleScript version without the Scripting Addition.
set theText to read file ((path to desktop as text) & "description.txt") as «class utf8» -- replace the HFS path with the actual path
set {TID, text item delimiters} to {text item delimiters, ("~~" & linefeed)}
set theMatches to text items of theText
set text item delimiters to TID
set theResult to {}
repeat with aMatch in theMatches
if length of aMatch > 1 then
tell aMatch
set end of theResult to {text 1 thru 4, text 7 thru -1}
end tell
end if
end repeat
I am trying to sort a list of file names in a created from one folder. Here is the code as it's simplest form. If I run this the 10 always comes after the 1 rather then the 9. What am I over looking.
set composer_list to {"Filename_1", "Filename_2", "Filename_3", "Filename_4", "Filename_5", "Filename_6", "Filename_7", "Filename_8", "Filename_9", "Filename_10", "Filename_11"}
simple_sort(composer_list)
--======================================= Sorting Handler =====================================
on simple_sort(my_list)
set the index_list to {}
set the sorted_list to {}
repeat (the number of items in my_list) times
set the low_item to ""
repeat with i from 1 to (number of items in my_list)
if i is not in the index_list then
set this_item to item i of my_list as text
if the low_item is "" then
set the low_item to this_item
set the low_item_index to i
else if this_item comes before the low_item then
set the low_item to this_item
set the low_item_index to i
end if
end if
end repeat
set the end of sorted_list to the low_item
set the end of the index_list to the low_item_index
end repeat
return the sorted_list
end simple_sort
Result:
{"Filename_1", "Filename_10", "Filename_11", "Filename_2", "Filename_3", "Filename_4", "Filename_5", "Filename_6", "Filename_7", "Filename_8", "Filename_9"}
Use:
considering numeric strings
simple_sort(composer_list)
end considering
Result:
{"Filename_1", "Filename_2", ..., "Filename_9", "Filename_10", "Filename_11"}
However, one variant to this problem that I had:
I had a list with hyphenated sections and subsections, using numbers separated by hyphens (section1, section1-3, section1-3-5, section2-0). Using the original simple_sort, 1-3-5 was coming in before 1-3. However, using "considering numeric strings" instead treated the hyphens as minus signs, and things were all jumbled. However, I added another subroutine to pre-treat the compared strings by removing the hypens before comparing:
on removeHyphens(theText)
set AppleScript's text item delimiters to "-"
set theReturn to every text item of theText
set AppleScript's text item delimiters to ""
set theReturn to theReturn as string
return theReturn
end removeHyphens
Then in the simple_sort function, I changed one line to this:
else if removeHyphens(this_item) comes before removeHyphens(low_item) then
This worked like a charm for this specific circumstance.
It's because
"Filename_11" comes before "Filename_2" -- true
If you zero pad the list, it should work.
"Filename_11" comes before "Filename_02" -- false
You should download Nigel Garvey's "A Dose of Sorts" for the best sorting routines.
how about
ignoring hyphen
...
end ignoring
but the best answer is: use Filename_01 (leading 0 padding)
Is there a way to check (in applescript) if a list (or block of html text) starts with any number of values.
Example (checking for a single value)
if {foobar starts with "<p>"} then
-- do something awesome here
end if
except i would like to pass multiple values to check <p> or <h1> or <em>.
Thanks in advance.
on startswith(txt, l)
repeat with v in l
if txt starts with v then return true
end repeat
false
end startswith
startswith("abc", {"a", "d", "e"}) -- true
If you want to stay within the 'English' style of AppleScript, although longer than the example above, you can just do this:
if {foobar starts with "hello" or foobar starts with "goodbye"} then
A full example would be:
set foobar to "hello dude"
if {foobar starts with "hello" or foobar starts with "goodbye"} then
display dialog "found"
end if
That will be true even if you change:
set foobar to "hello dude"
to:
set foobar to "goodbye dude"