I am trying to filter the output of my build system in SublimeText3.
First of all, can someone explain the difference between:
"file_regex": "",
"line_regex": "",
I want to catch the following line from this example output:
Compile success 0 Errors 0 Warnings Analysis time : 15.0 [ms]
.
VHDL/Verilog/EDIF/SystemC Simulator build 10.3.3558.6081
(c) 1997-2016 Aldec, Inc. All rights reserved.
License Number 0
Welcome to VSIMSA!
This message was printed from `startup.do' macro file.
# creating library
alib work
ALIB: Library `work' attached.
Compile success 0 Errors 0 Warnings Analysis time : 31.0 [ms]
Compile Package "BT601_cfg"
Compile success 0 Errors 0 Warnings Analysis time : 15.0 [ms]
# starting simulation with tb_top as the top level module
# asim fpc_tb
# running the simulation
# run 1000us
echo hi
hi
quit
First of all, can someone explain the difference between:
"file_regex": "",
"line_regex": "",
The file_regex is used in sublime-build systems to capture the locations of warnings, errors or things of that type to allow you to directly navigate to the associated location in the file that generated the message.
The regex should match on such lines by including anywhere from one to four regex captures which capture the following information:
file name
line number
column number
message text
The captures have to appear in this order, so if for example there is no column number but there is message text, you need to include an empty regex capture so that the capture on the message text is the fourth one.
The file and line/column information are used to allow Sublime to directly open the file and position the cursor at the appropriate location. The file name can be a relative path, in which case the folder set as the working_dir in your build file is used to determine where the file can actually be found.
The text of the message would be used for things such as inline error messages attached to the file window with phantoms, if you happen to have the appropriate feature turned on.
The line_regex is only needed in cases where the tool that you're running displays the name of the file on a line different than the line that contains the error.
In that case, you should provide a line_regex that has the following captures:
line number
column number
message text
If there is a line_regex set and it matches on a line, Sublime will look backwards through the results to find the first line that matches the file_regex you provided, allowing it to pick up the name of the file as well.
While you're working on setting up a build system, it can sometimes be helpful to open the Sublime console by selecting View > Show Console from the menu or pressing the associated key.
From there you can enter the following command and press enter:
sublime.log_result_regex(True)
This will get Sublime to log to the console what it's finding, so you can see if things are working as expected.
For example, given this example:
int main(int argc, char const *argv[])
{
printf("Hello, World!\n");
}
Building with the shipped C++ Single File build system generates the following output in the console:
Running g++ "/home/tmartin/test.c" -o "/home/tmartin/test"
found result file, line, col of [/home/tmartin/test.c], [3], [29] full path: /home/tmartin/test.c
More information on this topic can be found in the Official documentation as well as in the Unofficial documentation (linked here are the build system sections of both documentation sets).
I want to catch the following line from this example output:
Compile success 0 Errors 0 Warnings Analysis time : 15.0 [ms]
Since these regex values are for capturing the actual errors and warnings, it doesn't make sense to capture this particular line since it's not allowing you to navigate anywhere.
For your regex, you have to escape the \[ms\] or else this would mean a character set which would match m or s.
You also have 2 consecutive white spaces at 2 places (After Warnings and after time :) in your string instead of 1. These can be matched with just 2 white spaces.
You could update your regex to:
^Compile success [0-9]+ Errors [0-9]+ Warnings Analysis time : [0-9]+\.[0-9]+ \[ms\]
Related
We have an old, grown project with thousands of php files and need to clean it up.
Throughout the whole project we do have a lot of function calls similar to:
trans('somestring1');
trans("SomeString2");
trans('more_string',$somevar);
trans("anotherstring4",$somevar);
trans($tx_key);
trans($anotherKey,$somevar);
All of those are embedded into the code and represent translation keys. I would like to find a way to extract all "translation keys" in all occurrences.
The PHP project is in VS Code, so a RegEx Search would be helpful to list the results.
Or I could search through the project with any other tool you would recommend
However I would also need to "export" just the strings to a textfile or similar.
The ideal result would be:
somestring1
SomeString2
more_string
anotherstring4
$tx_key
$anotherKey
As a bonus - if someone knows, how I could get the above list including filename where the result has been found - that would be really fantastic!
Any help would be greatly appreciated!
Update:
The RegEx I came up with:
/(trans)+\([^\)]*\)(\.[^\)]*\))?/gim
list the full occurrence - How can I just get the first part of the result (between Single Quotes OR between Double Quotes OR beginning with $)
See here: regexr.com/548d4
Here are some steps to get exactly what you want. Using this you can do a find and replace on your search results!
So you could do sequential regex find/replaces in the right circumstances.
The replace can be just within the search results editor and not affect the underlying files at all - which is what you want.
You can also have the replace action actually edit the underlying files if you wish.
[Hint: This technique can also make doing a find item a / replace with b in files that contain term c much easier to do.]
(1) Open a new search editor: Ctrl+Shift+P
(That command is currently unbound to a keybinding.)
(2) Paste this regex into the Search input box (with the regex option .* selected):
`(.*?)(\btrans\(['"]?)([^,'")]+)(.*)` - a relatively simple regex
regex101 demo
See my other answer for a regex to work with up to 6 entries per line:
(\s*\d+:\s)?((.*?)(\btrans\(['"]?)([^,'")]*)((.*?)(\btrans\(['"]?)([^,'")]*))?((.*?)(\btrans\(['"]?)([^,'")]*))?((.*?)(\btrans\(['"]?)([^,'")]*))?((.*?)(\btrans\(['"]?)([^,'")]*))?((.*?)(\btrans\(['"]?)([^,'")]*))?)(.*)
(3) You will get a list of files with the search results. Now open a Find widget Shift+F in this Search editor.
(4) Put the same regex into that Find input. Regex option selected. Put $3 into the Replace field. This only replaces in this Search editor - not the original files (although that can be done if you want it in some case). Replace All.
If using the 1-6 version regex, replace with:
$1$5 $9 $13 $17 $21 $25
(5) Voila. You can now save this Search Editor as a file.
The first answer works for one desired capture per line as in the original question. But that relatively simple regex won't work if there are two or more per line.
The regex below works for up to 6 entries per line, like
trans('somestring1');
stuff trans("SomeString2"); some content trans("SomeString2a");more stuff [repeat, repeat]
But it doesn't for 7+ - you'll need a regex guru for that.
Here is the process again with a twist of using a snippet in the Search Editor instead of a Find/Replace. Using a snippet allows more control over the formatting of the final result.
(1) Open a new search editor: Ctrl+Shift+P (That command is currently unbound to a keybinding.)
(2) Paste this regex into the Search input box (with the regex option .* selected):
`((.*?)(\btrans\(['"]?)([^,'")]*)((.*?)(\btrans\(['"]?)([^,'")]*))?((.*?)(\btrans\(['"]?)([^,'")]*))?((.*?)(\btrans\(['"]?)([^,'")]*))?((.*?)(\btrans\(['"]?)([^,'")]*))?((.*?)(\btrans\(['"]?)([^,'")]*))?)(.*)`
regex101 demo
(3) You will get a list of files with the search results. Now select all your results individually with Ctrl+Shift+L.
(4) Trigger this keybinding:
{
"key": "alt+i", // whatever keybinding you like
"command": "editor.action.insertSnippet",
"when": "editorTextFocus",
"args": {
"snippet": "${TM_SELECTED_TEXT/((.*?)(\\btrans\\([\\'\\\"]?)([^,\\'\\\")]*)((.*?)(\\btrans\\([\\'\\\"]?)([^,\\'\\\")]*))?((.*?)(\\btrans\\([\\'\\\"]?)([^,\\'\\\")]*))?((.*?)(\\btrans\\([\\'\\\"]?)([^,\\'\\\")]*))?((.*?)(\\btrans\\([\\'\\\"]?)([^,\\'\\\")]*))?((.*?)(\\btrans\\([\\'\\\"]?)([^,\\'\\\")]*))?)(.*)/$4${8:+\n }$8${12:+\n }$12${16:+\n }$16${20:+\n }$20${24:+\n }$24/g}"
}
},
That snippet will be applied to each selection in your search result. This part ${8:+\n } is a conditional which adds a newline and some spaces if there is a capture group 8 - which would be a second trans(...) on a line.
Demo: (unfortunately, it doesn't properly show the Ctrl+Shift+L selecting all lines individually or the Alt+i snippet trigger)
I want to filter everything from a log that belongs to a particular user.
With the following pattern, and the ". matches newline" option enabled, I can match everything that I am looking for, but when I ask Notepad++ to bookmark these line so I can copy them, something strange happens.
([^\n]+)userB(.+?)(?=([0-9]{4}-[0-9]{2}-[0-9]{2}))
In front of line 2 and 8 I see a bookmark icon, but the lines: 3,4,5 and 9,10,11 are missing an icon, although they belong to the highlighted text.
Why does Notepad++ highlight the text, but doesn't place the bookmark correctly? And more importantly, how can I fix this?
Here is the log that I am using:
2015-03-02 11:28:44,993 INFO application [http-0.0.0.0-8080-17] userA 99:7 12345 some message
2015-03-02 11:28:45,468 WARN application [http-0.0.0.0-8080-9] userB 12:2 some message
extra information
at some.classes.and.function(Filename.java:123)
at some.classes.and.function(Filename.java:123)
2015-03-02 11:28:44,993 INFO application [http-0.0.0.0-8080-17] userA 99:7 12345 some message
2015-03-02 11:28:44,993 INFO application [http-0.0.0.0-8080-17] userA 99:7 12345 some message
2015-03-02 11:28:45,468 WARN application [http-0.0.0.0-8080-9] userB 12:2 some message
extra information
at some.classes.and.function(Filename.java:123)
at some.classes.and.function(Filename.java:123)
2015-03-02 11:28:44,993 INFO application [http-0.0.0.0-8080-17] userA 99:7 12345 some message
The following will extract the information you want without using bookmarks and should work in Notepad++ version 6.9.1 onwards.
It assumes that the lines of extra information don't start with a digit.
It deletes the copied lines from the data file so work on a copy of the data file if you want to preserve it.
It is not very efficient because the switch tab command positions the cursor back at the start of a tab's text.
It duplicates the last match for userB. (A minor irritant!)
Description
1) Define shortcuts for switching to next & previous tabs
2) Open the data file with Notepad++
3) Open a new tab then go back to the data file tab
4) Define a macro `Cut User data. Paste in next tab`
5) Run the macro `Cut User data. Paste in next tab` on the data file to `end of file`
(It needs to be run once prior to running it in `Run a Macro Multiple Times`
because of a quirk of Notepad++)
Method
1) Settings Shortcut Mapper Main menu
Switch to previous document = Ctrl+Alt+Left
Switch to next document = Ctrl+Alt+Right
Close
2) Open data file with Notepad++
3) File New Ctrl+Alt+Left
4) Start Recording
Find Find what: .+ userB.+\r\n(\D.+\r\n)*
Search Mode = Regular expression
Find Next Alt+F4
Ctrl+X Ctrl+Alt+Right
Ctrl+End Ctrl+V Ctrl+Alt+Left
Stop recording
Save Current Recorded Macro
Name: Cut User data. Paste in next tab OK
5) Macro Cut User data. Paste in next tab
Run a Macro Multiple Times
Macro to run: Cut User data. Paste in next tab
Run until end of file = Yes
Run then when it has stopped Cancel
(Editted to be an answer.)
At least in the current version of Notepad++ the macro halts while the switch dialog box appears when using the macro solution and switching tabs.
You must first go to settings, MISC., document switcher, and disable both check boxes. This is at least true in v7.6.
I am trying to search thru log files to see if any warnings have appeared so that I can warn in a Jenkins pipeline using Jenkins plug in "Text Finder".
However, I have a case where I do not want hits on the string "CRIT" int he logfile if the string also contains plms.
E.g.
I have the following text in the log file:
<CRIT> 23-Jun-2014::10:57:13.649 Upgrade committed
<CRIT> 23-Jun-2014::10:57:13.703 no registration found for callpoint plmsView/get_next of type=external
I am not interested in having a warning for the second line, so I have added the following regex to Text Finder in Jenkins:
WARN|ERROR|<ERR>|/^(?=<CRIT>)(?=^(?:(?!plms).)*$).*$/
This should get a hit on CRIT only if the string does not also contain plms, i.e the first line, but I do not get a hit on either line.
I got the code from here: Combine Regexp
Could someone please help me correct this? Thanks!
You should use something like this:
WARN|ERROR|<ERR>|<CRIT>(?!.*?no registration found)
Change the no registration found part to match the <CRIT> message you want to exclude.
This expression matches also for the line:
<INFO> User WARNER registered
so you should consider using something like:
^(WARN|ERROR|<ERR>|<CRIT>(?!.*?no registration found))
that matches only if the tokens are at the beginning of the line (change the tokens accordingly).
This should work for you:
^<CRIT>(.(?!plms))*$
Demo and explanation
I'm trying to setup Sublime Text 2 so that I can code my Oracle packages, triggers, functions, etc. I have the build system compiling my code just fine. Now I'm working on trying to get Sublime Text to take me to the exact line/column position when an error happens. To do this you have to use the file_regex option documented here.
The file_regex option uses a Perl-style regular expression to capture
up to four fields of error information from the build program’s
output, namely: filename, line number, column number and error
message. Use groups in the pattern to capture this information. The
filename field and the line number field are required.
My problem seems to be filename, which is the first required thing. My question is at the very bottom but let me show you how everything is setup because others may find this useful.
Here is my build system (compileSql.sublime-build)...
{
"cmd": ["c:\\projectX\\compileSql.bat", "$file"],
"file_regex": "^([0-9]+)/([0-9]+)"
}
Here is compileSql.bat. All this does is it makes a new file called runFile.txt which contains the file I'm currently working on in Sublime text, except it starts the file off with set defined off;, then my code, then ends with show errors; It then logs in and compiles the package (trigger, function, whatever)...
#echo set define off; > c:\projectX\runFile.txt
type %1 >> c:\projectX\runFile.txt
#echo show errors; >> c:\projectX\runFile.txt
sqlplus -s {user}/{pwd}#{database} #c:\projectX\runFile.txt
So all I have to do is press F7 and it compiles for me...
But when I get an error, this is the result...
When I click on the error is doesn't take me to that line number. Instead it opens a file called 8. So back up to my build system, I know the problem is with this: "file_regex": "^([0-9]+)/([0-9]+)". Sublime Text 2 requires the first matched pattern to be the file. That's the part I'm not grasping, why does it need to know that? It's the file I'm working on, the one I just pressed F7 for. So something needs to come before the ([0-9]+)/([0-9]+) in the regular expression, I don't know what to put in there.
I'm working on a C++ project which should do following operations:
Open a .txt file which contains list of strings
(for example String1: "Hi,name_1_is,;Ondrej,age24;year,,88;") with optional values determined by empty commas ",,".
After this check each string using regular expressions for valid input
(like "Hi" shouldn't be a number or "1" must be a number and everything with ",," is optional and can be skipped or user can enter this value as well).
Then evaluate the result and save it to variable or new .txt generated file.
This result shows if whole string is correct with an "ok" message attached to it or it will attach "not ok" message right to the parameter with wrong input.
I have already finished the part with opening a .txt file, checking the whole string and saving the right strings to the new file (using Qt and Visual Studio 2010 Express).
I need to do the part where each parameter will be checked but somehow I don't know how exactly, as I should not build Parser but the whole programm must be build like Interpreter.
Actually I'm stucked at this point because I have no idea how to start to build this like an Interpreter.
All my attempts resulted always with structure similar to Parser
(that means: I used split string, then checked each token or char using regex, then built the string together again, ect.)
Could you provide me with some usefull links or tips of how to achieve that or at least where to start at all please?