Simple question for someone who know little C shell programming
I am posting some code lines of my program
........
set gramma = $<
else if ($gramma == 's') then
echo " ta defterolepta pou menoun ine " secs_remain
else if ($gramma == 'm') then
# min = $secs_remain % 60
# secs = $secs_remain - ($min*60)
echo " o xronos pou meni ine " min " lepta ke " secs " defterolepta "
else if ($gramma == 'h') then
.........
My question is about the character. As you can see I am reading a character from the keyboard.
On the if command, does my character need the ' and '?
Or can i simply write the character?
For example
if ($gramma == 's') then
or
if ($gramma == s) then
I know that if it was a string it will be
if ($gramma == "sexy") then
and if a number
if ($gramma == 4) then
What about a single character?
I think you are asking should the right hand side of a comparison always be wrapped in single quote chars? == 'm' (right hand side)
AND OF course, the answer is it depends
Single quotes mean that any variable values inside will NOT be expanded to the value that was assigned. If you you have variable values, quote them with double-quote chars.
You can leave out single OR double quotes if you're really,really,really sure you're never going to have a value on the right-hand-side that evaluates to a multi-'word' value with white space chars. You really need quoting (single or double) to avoid problems with white space chars.
I think the general consensus among people that write books about shell coding is that you always want to surround the left-and-right-hand sides of a string comparison operations (==, !=, ~=) with appropriate quotes, double if variable expansion required, single if not.
Hello I am trying to build a simple action in Ruby that takes one string like
result = "This is my javascript variable 'var first = 1 + 1;' and here is another 'var second = 2 + 2;' and that's it!"
So basically I would like to take the text within single quotes ' or backticks ` and and replace it by:
<code>original text</code> note I'm replacing it by an opening and closing code tag
Just like in markdown
so I would have a result like
result = "This is my javascript variable <code>var first = 1 + 1;<code> and here is another <code>var second = 2 + 2;</code> and that's it"
If it's possible to run this natively without the need of any extra gem it would be great :)
Thanks a lot
I guess you'll need to iterate the string and parse it. While you can do non-greedy regex matches, e.g. result.gsub!(/'([^']*)'/, '<code>\1</code>') you might find the result might not behave correctly in corner-cases.
Without any other advanced requirement
>> result.gsub(/\s+'/,"<code>").gsub(/'\s+/,"</code>")
=> "This is my javascript variable<code>var first = 1 + 1;</code>and here is another<code>var second = 2 + 2;</code>and that's it!"
You will need to come-up with a character as a delimiter for your code, which you don't use otherwise..
Why? because of all the corner cases. E.g. the following string
result = "This's my javascript variable 'var first = 1 + 1;' and here is another 'var second = 2 + 2;' and that's it!"
which would otherwise produce:
"This<code>s my javascript variable </code>var first = 1 + 1;<code> and here is another </code>var second = 2 + 2;<code> and that</code>s it!"
Total garbage out..
However if you use a unique character as a delimiter that's otherwise not used, you can create a non-greedy RegExp which will do the search/replace
e.g. using a # character to delimit the code:
"This's my javascript variable #var first = 1 + 1;# and here is another #var second = 2 + 2;# and that's it!"
I'm trying to write a simple script expression that allows me to identify the java files in a directory that have a private constructor. I have had some luck but I want my script to acknowledge there is white space between the access modifier and the constructor name but not care if it is a space or n spaces or a tab or n tabs etc.
I am trying to use...
"private\s+"+object_name
but the + (1 or more) is not finding a constructor with 2 spaces between the modifier and the constructor name.
I know I am missing something. Any help would be greatly appreciated.
Thanks.
Here is the full code if it helps...
!#/usr/bin/ruby
path = ARGV[0]
if path.nil?
puts "missing path argument"
exit
end
entries = Dir.entries( path )
entries.each do |file_name|
file_name = file_name.rstrip
if ( file_name.end_with? "java" )
text = File.read( path+file_name )
object_name = file_name.chomp( ".java" )
search_str = "private\s+"+object_name
matches = text.match( Regexp.escape( search_str ) )
if ( !matches.nil? && matches.length > 0 )
puts matches
end
end
end
I think you want to escape the \ in your Ruby string and also Regexp.escape your object name and not the whole regex including the whitespace matcher, e.g.,
[...]
search_regex = Regexp.new("private\\s+" + Regexp.escape(object_name))
matches = text.match(search_regex)
As #LBg also points out, if you want to use + concatenation, better to use single quotes that won't require escaping the \. Or use doubles with substitution as in:
search_regex = Regexp.new("private\\s+#{Regexp.escape(object_name)}")
A double-quoted string reads "\s" as " ", no problems with that, but prefer use single-quoted in this case. Regexp.escape removes the funcionality of the regex's symbols of the string. private + ("\s" is " ") is converted to private\ \+ and, with match, will try to find the string private +object_name, what is not what you want. Remove the Regexp.escape and it should work well.
I need to be able to match a certain string ('[' then any number of equals signs or none then '['), then i need to match a matching close bracket (']' then the same number of equals signs then ']') after some other match rules. ((options{greedy=false;}:.)* if you must know). I have no clue how to do this in ANTLR, how can i do it?
An example: I need to match [===[whatever arbitrary text ]===] but not [===[whatever arbitrary text ]==].
I need to do it for an arbitrary number of equals signs as well, so therein lies the problem: how do i get it to match an equal number of equals signs in the open as in the close? The supplied parser rules so far dont seem to make sense as far as helping.
You can't easely write a lexer for it, you need parsing rules. Two rules should be sufficient. One is responsible for matching the braces, one for matching the equal signs.
Something like this:
braces : '[' ']'
| '[' equals ']'
;
equals : '=' equals '='
| '=' braces '='
;
This should cover the use case you described. Not absolute shure but maybe you have to use a predicate in the first rule of 'equals' to avoid ambiguous interpretations.
Edit:
It is hard to integrate your greedy rule and at the same time avoid a lexer context switch or something similar (hard in ANTLR). But if you are willing to integrate a little bit of java in your grammer you can write an lexer rule.
The following example grammar shows how:
grammar TestLexer;
SPECIAL : '[' { int counter = 0; } ('=' { counter++; } )+ '[' (options{greedy=false;}:.)* ']' ('=' { counter--; } )+ { if(counter != 0) throw new RecognitionException(input); } ']';
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
rule : ID
| SPECIAL
;
Your tags mention lexing, but your question itself doesn't. What you're trying to do is non-regular, so I don't think it can be done as part of lexing (though I don't remember if ANTLR's lexer is strictly regular -- it's been a couple of years since I last used ANTLR).
What you describe should be possible in parsing, however. Here's the grammar for what you described:
thingy : LBRACKET middle RBRACKET;
middle : EQUAL middle EQUAL
| LBRACKET RBRACKET;
The built-in VIM :sort command sorts lines of text. I want to sort words in a single line, e.g. transform the line
b a d c e f
to
a b c d e f
Currently I accomplish this by selecting the line and then using :!tr ' ' '\n' | sort | tr '\n' ' ', but I'm sure there's a better, simpler, quicker way. Is there?
Note that I use bash so if there's a shorter and more elegant bash command for doing this it's also fine.
EDIT: My use-case is that I have a line that says SOME_VARIABLE="one two three four etc" and I want the words in that variable to be sorted, i.e. I want to have SOME_VARIABLE="etc four one three two".
The end result should preferably be mappable to a shortcut key as this is something I find myself needing quite often.
In pure vim, you could do this:
call setline('.', join(sort(split(getline('.'), ' ')), " "))
Edit
To do this so that it works over a range that is less than one line is a little more complicated (this allows either sorting multiple lines individually or sorting part of one line, depending on the visual selection):
command! -nargs=0 -range SortWords call SortWords()
" Add a mapping, go to your string, then press vi",s
" vi" selects everything inside the quotation
" ,s calls the sorting algorithm
vmap ,s :SortWords<CR>
" Normal mode one: ,s to select the string and sort it
nmap ,s vi",s
function! SortWords()
" Get the visual mark points
let StartPosition = getpos("'<")
let EndPosition = getpos("'>")
if StartPosition[0] != EndPosition[0]
echoerr "Range spans multiple buffers"
elseif StartPosition[1] != EndPosition[1]
" This is a multiple line range, probably easiest to work line wise
" This could be made a lot more complicated and sort the whole
" lot, but that would require thoughts on how many
" words/characters on each line, so that can be an exercise for
" the reader!
for LineNum in range(StartPosition[1], EndPosition[1])
call setline(LineNum, join(sort(split(getline('.'), ' ')), " "))
endfor
else
" Single line range, sort words
let CurrentLine = getline(StartPosition[1])
" Split the line into the prefix, the selected bit and the suffix
" The start bit
if StartPosition[2] > 1
let StartOfLine = CurrentLine[:StartPosition[2]-2]
else
let StartOfLine = ""
endif
" The end bit
if EndPosition[2] < len(CurrentLine)
let EndOfLine = CurrentLine[EndPosition[2]:]
else
let EndOfLine = ""
endif
" The middle bit
let BitToSort = CurrentLine[StartPosition[2]-1:EndPosition[2]-1]
" Move spaces at the start of the section to variable StartOfLine
while BitToSort[0] == ' '
let BitToSort = BitToSort[1:]
let StartOfLine .= ' '
endwhile
" Move spaces at the end of the section to variable EndOfLine
while BitToSort[len(BitToSort)-1] == ' '
let BitToSort = BitToSort[:len(BitToSort)-2]
let EndOfLine = ' ' . EndOfLine
endwhile
" Sort the middle bit
let Sorted = join(sort(split(BitToSort, ' ')), ' ')
" Reform the line
let NewLine = StartOfLine . Sorted . EndOfLine
" Write it out
call setline(StartPosition[1], NewLine)
endif
endfunction
Using great ideas from your answers, especially Al's answer, I eventually came up with the following:
:vnoremap <F2> d:execute 'normal i' . join(sort(split(getreg('"'))), ' ')<CR>
This maps the F2 button in visual mode to delete the selected text, split, sort and join it and then re-insert it. When the selection spans multiple lines this will sort the words in all of them and output one sorted line, which I can quickly fix using gqq.
I'll be glad to hear suggestions on how this can be further improved.
Many thanks, I've learned a lot :)
EDIT: Changed '<C-R>"' to getreg('"') to handle text with the char ' in it.
Here's the equivalent in pure vimscript:
:call setline('.',join(sort(split(getline('.'),' ')),' '))
It's no shorter or simpler, but if this is something you do often, you can run it across a range of lines:
:%call setline('.',join(sort(split(getline('.'),' ')),' '))
Or make a command
:command -nargs=0 -range SortLine <line1>,<line2>call setline('.',join(sort(split(getline('.'),' ')),' '))
Which you can use with
:SortLine
:'<,'>SortLine
:%SortLine
etc etc
:!perl -ne '$,=" ";print sort split /\s+/'
Not sure if it requires explanation, but if yes:
perl -ne ''
runs whatever is within '' for every line in input - putting the line in default variable $_.
$,=" ";
Sets list output separator to space. For example:
=> perl -e 'print 1,2,3'
123
=> perl -e '$,=" ";print 1,2,3'
1 2 3
=> perl -e '$,=", ";print 1,2,3'
1, 2, 3
Pretty simple.
print sort split /\s+/
Is shortened version of:
print( sort( split( /\s+/, $_ ) ) )
($_ at the end is default variable).
split - splits $_ to array using given regexp, sort sorts given list, print - prints it.
Maybe you prefer Python:
!python -c "import sys; print(' '.join(sorted(sys.stdin.read().split())))"
Visual select text, and execute this line.
My AdvancedSorters plugin now has a :SortWORDs command that does this (among other sorting-related commands).