I've been trying to figure something out for a while now and I can't seem to understand. I've looked everywhere and I still can't find it.
I'm trying to make a dictionary for an auto corrector with AutoHotKey and I need to replace the beginning of each line with "::" and somewhere in between the line with another "::"
like so:
::togehter::together
Now I have around 20,000 of these to add with no "::" yet and what I'm doing is this in the replace textbox:
Replace: ^
With: ::
Now it works fine for the first line BUT if I press replace all cause no way am I going to click 20,000 times on replace, it replaces not only from where I am to the bottom but also the beginning too. So every line now has a new "::" added.
So what I need is to be able to tell the replace at what line to stop instead of doing every single line.
Also if you could help me add the "::(word)" after the first ::(misspelled word) that would be a great help.
Image for reference
I have found that the regular expression replace-all of ^ with some text, i.e. to add some text at the start of every line, does not work in some versions of Notepad++. My workaround for this was to use the ^(.) as the search string and include \1 in the replacement. For your case the replacement would be ::\1. The effect here is to replace the first character of each line with :: plus the first character. In a quick test with Notepad++ v7.1, replacing ^ with :: worked as I would want.
Two things should be checked in the Replace dialogue before doing the replace-all: (1) that "Regular expression" is selected and (2) "In selection" is not selected.
The question is not clear how the two words in the input are separated, so assuming that one or more spaces or tabs is used the search string to use is ^(\w+)\h+ and the replace string is ::\1::.
This AutoHotkey script might do what you require.
It leaves unchanged lines that start with '::',
and prepends/replaces text in the others. You copy the original text to the clipboard, run this script, and then the desired text is put on the clipboard. (To create and run the script: copy and paste it into a text editor and save it as myscriptname.ahk, or myscriptname.txt and then drag and drop the file into the AutoHotkey exe file. Or alternatively, if you save it as an ahk file, and install AutoHotkey, you can double-click to run.) AutoHotkey
vText := Clipboard
vOutput := ""
VarSetCapacity(vOutput, StrLen(vText)*2*2)
StringReplace, vText, vText, `r`n, `n, All
Loop, Parse, vText, `n
{
vTemp := A_LoopField
if (vTemp = "")
if (1, vOutput .= "`r`n")
continue
if (SubStr(vTemp, 1, 2) = "::")
if (1, vOutput .= vTemp "`r`n")
continue
StringReplace, vTemp, vTemp, %A_Space%, ::, All
vOutput .= "::" vTemp "`r`n"
}
Clipboard := vOutput
MsgBox done
Return
Related
I need a tip, tip or suggestion followed by some example of how I can add an extension in .txt format after the last character of a variable's output line.
For example:
set txt " ONLINE ENGLISH COURSE - LESSON 5 "
set result [concat "$txt" .txt]
Print:
Note that there is space in the start, means and fin of the variable phrase (txt). What must be maintained are the spaces of the start and means. But replace the last space after the end of the sentence, with the format of the extension [.txt].
With the built-in concat method of Tcl, it does not achieve the desired effect.
The expected result was something like this:
ONLINE ENGLISH COURSE - LESSON 5.txt
I know I could remove spaces with string map but I don't know how to remove just the last occurrence on the line.
And otherwise I don’t know how to remove the last space to add the text [.txt]
If anyone can point me to one or more solutions, thank you in advance.
set result "[string trimright $txt].txt"
or
set result [regsub {\s*$} $txt ".txt"]
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 have some large files (bigger than 2GB ), and the text in the files has the following format:
2013/4/18;22:5:42.668;13266;10;13279;10
2013/4/18;22:10:48.820;13271;10;13279;10
2013/4/18;22:12:0.956;13266;10;13279;10
2013/4/18;22:12:44.826;13266;10;13284;10
...
I would like to accomplish the following task
- replace the 1st semi-colon ";" in each line to space character " "
- replace the rest semi-colon ";" in each line to comma character ","
The output should look like as below
2013/4/18 22:5:42.668,13266,10,13279,10
2013/4/18 22:10:48.820,13271,10,13279,10
2013/4/18 22:12:0.956,13266,10,13279,10
2013/4/18 22:12:44.826,13266,10,13284,10
...
Can any one please advise me how to ?
Though this is not a regex this will do your work!
This is called emacs keyborad macro!
These are the keys you need to press after opening this file in emacs.
Why I am asking you to define you the macro is because once defined you can use it anytime for any file by just pressing one or two keys.
Open your file in emacs and start pressing these keys:
alt-shift-, //go to the start of the file
ctrl-x-( //start defining keyboard macro
ctrl-s //search for some thing
; //that something is your ;
ctrl-b //move one step back
ctrl-d //delete the ;
[space-bar] //add space
ctrl-[space-bar] //start selecting region
ctrl-e //select region till the end of line
alt-shift-5 //replace all from region
; //replace ;
, //with ,
shift-1 //do this for all ; in region
ctrl-e //move to end of line
ctrl-f //go to start of next line
ctrl-x-) //end macro
//now-your-macro-is-defined
ctrl-[space-bar] //again define the region
alt-shift-. //select all file (except first line)
M-x-apply-macro-to-region //apply perviously defined macro to complete file!
hope this helps!
It can be done easily in gVim for Windows. First, we replace the 1st semi-colon in each line with space by a simple macro. To enter the macro, type:
ggq1(or any letter)^f;r jq
explanation:
gg: go to the start of the file
q1: start recording to register 1 or anywhere
^: go to the start of a line
f;: go to the occurrence of ; to the right
r: replace the character under the cursor with space
j: go to next line
q: stop recording
then execute the macro from the second line by type :2,$:normal #1 in command mode, now the 1st semi-colons of all lines are replaced by a space. After that, use :%s/;/,/g to replace the rest semi-colons.
Here is a perl one liner that does the job:
perl -api.back -e 's/;/ /; s/;/,/g;' in.txt
The original file is save under in.txt.back and the replacement is done in-place.
I am trying to look for a specific keyword in multi-line input string like this,
this is input line 1
this is the keyword line
this is another input line
this is the last input line
The multi-line input is stored in a variable called "$inputData". Now, I have 2 ways in mind to look for the word "keyword",
Method 1:
Using split to put the lines into an array using "\n" separator and iterate and process each line using foreach loop, like this,
my #opLines = split("\n", $inputData);
# process each line individually
foreach my $opLine ( #opLines )
{
# look for presence of "keyword" in the line
if(index($opLine, "keyword") > -1)
{
# further processing
}
}
Method 2:
Using regex, as below,
if($inputData =~ /keyword/m)
{
# further processing
}
I would like to know how these 2 methods compare with each other and What would be the better method with regards to actual code performance and execution time. Also, is there a better and more efficient way to go about this task?
my #opLines = split("\n", $inputData);
Will create variable #opLines, allocate memory, and search "\n" trough whole $inputData and write found lines into it.
# process each line individually
foreach my $opLine ( #opLines )
{
Will process the whole bunch of code for each value in array #opLines
# look for presence of "keyword" in the line
if(index($opLine, "keyword") > -1)
Will search for the "keyword" in each line.
{
# further processing
}
}
And comapare
if($inputData =~ /keyword/m)
Will search for the "keyword" and stops when find first occurrence.
{
# further processing
}
And now guess, what will be faster and consume less memory (which affects speed as well). If you are bad in guessing use Benchmark module.
According documentation m regular expression modifier: Treat string as multiple lines. That is, change "^" and "$" from matching the start or end of line only at the left and right ends of the string to matching them anywhere within the string. I don't see neither ^ nor $ in your regexp so it is useless there.
I'm trying to formulate a regular expression that matches the names of a set of files I would like to batch process in Vim but am finding that I cannot seem to use \| (regex OR) as expected...
Specifically, I would like to create an argument list consisting of the following files in the current directory:
f0148.e, f0149.e, f0150.e ... f0159.e (i.e., 12 files total)
The vim command I entered goes as follows:
:arg f01\(\(4[89]\)\|\(5[0-9]\)\).e
Vim completes this command without any noticeable result -- there's no message and the output from :args remains unchanged (doesn't produce the desired list of file names).
If I split up the regular expression to:
:arg f01\(\(4[89]\)\).e (note: leaving parenthesis here as in above full expression)
...and...
:arg f01\(\(5[0-9]\)\).e
... then :args produces f0148.e f0149.e and f0150.e ... f0159.e respectively (as desired).
Also, if I enter the above mentioned list of file names in a text file and use the above mentioned regular expression as a search pattern (i.e., /f01\(\(4[89]\)\|\(5[0-9]\)\).e), it works just as desired.
Thus, I determined that the alternation (\|) is somehow causing the the expression to fail. Please note that I'm using Vim on Windows 7, if this is relevant (since both backslash and pipe are valid symbols at the Windows command prompt).
A quick workaround would be to use:
:arg f014[89].e
:argadd f015[0-9].e
...but I would really like to figure out how to make the above regular expression work.
Thanks for your help!
I could suggest:
:let file_list = filter(split(globpath('.','**'),nr2char(10)), 'v:val =~ ''f01\(\(4[89]\)\|\(5[0-9]\)\)\.e'' ')
:execute 'args ' . join(map(file_list,'fnameescape(v:val)'),' ')
How this works:
globpath('.','**') makes a list of all files in current directory and all subdirectories. :help globpath().
split(..., nr2char(10)) will make a list of it, because the separator was Line Feed
filter(..., 'v:val =~ ''pattern'' ') filters the list keeping only items matching pattern. :help v:val. Doubling single quote is escaping them inside single quote string.
map(..., fnameescape()) escapes all spaces and backslashes
join() adds spaces between file names
If you want to make it a function you can put this into your vimrc:
function! ArgsPattern(pat)
let file_list = filter(split(globpath('.','**'),nr2char(10)), 'v:val =~ ''' . substitute(a:pat,"'","''",'g') . '''')
execute 'args ' . join(map(file_list,'fnameescape(v:val)'),' ')
endfunction
command! -nargs=+ ArgsPattern call ArgsPattern(<q-args>)
And then you only have to do:
:ArgsPattern f01\(\(4[89]\)\|\(5[0-9]\)\)\.e
Note that if there is no match, then the execute command inside the function evaluates to :args and therefore the list of your current arguments are printed.