文章来自于:http://hyperpolyglot.org/scripting
a side-by-side reference sheet
sheet one: grammar and invocation | variables and expressions | arithmetic and logic | strings | regexes | dates and time| arrays | dictionaries | functions | execution control | exceptions | concurrency
sheet two: file handles | files | file formats | directories | processes and environment | option parsing | libraries and namespaces | objects | polymorphism | reflection | net and web | unit tests | debugging and profiling | java interop
perl | php | python | ruby | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
versions used |
5.14; 5.16 | 5.4; 5.5 | 2.7; 3.3 | 1.9; 2.0 | |||||||||||
show version |
$ perl --version | $ PHP --version | $ python -V $ python --version |
$ ruby --version | |||||||||||
implicit prologue |
use strict; | none | import os,re,sys | none | |||||||||||
grammar and invocation | |||||||||||||||
perl | PHP | python | ruby | ||||||||||||
interpreter |
$ perl foo.pl | $ PHP -f foo.PHP | $ python foo.py | $ ruby foo.rb | |||||||||||
repl |
$ perl -de 0 | $ PHP -a | $ python | $ irb | |||||||||||
command line program | $ perl -e 'print("hi\n")' | $ PHP -r 'echo "hi\n";' | $ python -c 'print("hi")' | $ ruby -e 'puts "hi"' | |||||||||||
block delimiters |
{} | : and offside rule | {} do end |
||||||||||||
statement separator |
; | ; statements must be semicolon terminated inside {} |
newline or ; newlines not separators inside (),[],{},triple quote literals,or after backslash: \ |
``,'',"",or after binary operator or backslash: \ | |||||||||||
source code encoding | utf8; | Python 3 source is UTF-8 by default # -*- coding: utf-8 -*- |
Ruby 2.0 source is UTF-8 by default # -*- coding: utf-8 -*- |
||||||||||||
end-of-line comment |
# comment | // comment # comment |
# comment | ||||||||||||
multiple line comment |
=for comment line another line =cut |
/* comment line another line */ |
use triple quote string literal: '''comment line another line''' |
=begin comment line another line =end |
|||||||||||
variables and expressions | |||||||||||||||
local variable | my $v; my (@a, %d); my $x = 1; my ($y, $z) = (2,3); |
# in function body: $v = NULL; $a = []; $d = []; $x = 1; list($y,$z) = [2,3]; |
# in function body: v = None a,63)">d = [],{} x = 1 z = 2,3 |
v = nil a,d = [],{} x = 1 y,z = 2,3 |
|||||||||||
regions which define lexical scope | top level: file nestable: function body anonymous function body anonymous block |
top level: function or method body nestable (with use clause): anonymous function body |
nestable (read only): function or method body |
top level: file class block module block method body nestable: anonymous function body anonymous block |
|||||||||||
global variable | our ($g1,63)">$g2) = (7,8); sub swap_globals { ($g1,$g2) = ($g2,$g1); } |
list($g1,63)">g2) = [7,8]; function swap_globals() { global $g2; list($g2) = [$g2,63)">g1]; } |
g2 = 7,8 def swap_globals(): global g1,g2 g1,g2 = g2,g1 |
$g2 = 7,205)">swap_globals $g2 = $g2,63)">$g1 end |
|||||||||||
constant |
constant PI => 3.14; | define("PI",3.14); | # uppercase identifiers # constant by convention PI = 3.14 |
# warning if capitalized # identifier is reassigned PI = 3.14 |
|||||||||||
assignment |
$v = 1; | $v = 1; | assignments can be chained but otherwise don't return values: v = 1 |
v = 1 | |||||||||||
parallel assignment |
($x,$y,$z) = (1,2,3); # 3 is discarded: ($x,$y) = (1,3); # $z set to undef: ($x,2); |
x,63)">z) = [1,3]; # 3 is discarded: list($y) = [1,3]; # $z set to NULL: list($z = 1,3 # raises ValueError: y = 1,2 |
x,y,z = 1,3 # 3 is discarded: x,y = 1,3 # z set to nil: x,2 |
||||||||||||
swap |
y) = [$x]; | y = y,x | compound assignment arithmetic,string,logical,bit |
+= -= *= none /= %= **= .= x= &&= ||= ^= <<= >>= &= |= ^= |
+= -= *= none /= %= **= .= none &= |= none <<= >>= &= |= ^= |
# do not return values: += -= *= /= //= %= **= += *= &= |= ^= <<= >>= &= |= ^= |
+= -= *= /= none %= **= += *= &&= ||= ^= <<= >>= &= |= ^= |
||||||||
increment and decrement |
$x = 1; my $y = ++$x; my $z = --$y; |
x = 1; $y = ++$x; $z = --$y; |
x = 1 # x and y not mutated: y = x.succ z = y.pred |
||||||||||||
null |
undef | NULL # case insensitive | None | nil | |||||||||||
null test |
! defined $v | is_null($v) ! isset($v) |
v == None v is None |
v == nil v.nil? |
|||||||||||
undefined variable access |
error under use strict; otherwise undef | NULL | raises NameError | raises NameError | |||||||||||
conditional expression |
$x > 0 ? $x : -$x | x > 0 ? $x : -$x | x if x > 0 else -x | x > 0 ? x : -x | |||||||||||
arithmetic and logic | |||||||||||||||
true and false | 1 "" | TRUE FALSE # case insensitive | True False | true false | |||||||||||
falsehoods |
undef 0 0.0 "" "0" () | FALSE NULL 0 0.0 "" "0" [] | False None 0 0.0 '' [] {} | false nil | |||||||||||
logical operators |
&& || ! lower precedence: and or xor not |
&& || ! lower precedence: and or xor |
and or not | && || ! lower precedence: and or not |
|||||||||||
relational operators |
numbers only: == != > < >= <= | == != or <> > < >= <= no conversion: === !== |
relational operators are chainable: == != > < >= <= |
== != > < >= <= | |||||||||||
compare strings | eq ne gt lt ge le | min and max |
List::Util qw(min max); min(1,3); max(1,3); @a = (1,3); min(@a); max(@a); |
min(1,3) max(1,3) $a = [1,3] min($a) max($a) |
min(1,3) max(1,3) min([1,3]) max([1,3]) |
[1,3].min [1,3].max |
|||||||||
three value comparison | 0 <=> 1 "do" cmp "re" |
removed from Python 3: cmp(0,1) cmp('do', 're') |
0 <=> 1 "do" <=> "re" |
||||||||||||
arithmetic operators addition,subtraction,multiplication,float division,quotient,remainder |
+ - * / none % | + - * see note // % Python 2 does not have an operator which performs float division on integers. In Python 3 / always performs float division. |
+ - * x.fdiv(y) / % | ||||||||||||
integer division |
int(13 / 5) | (int)(13 / 5) | 13 // 5 | 13 / 5 | |||||||||||
divmod |
q,r = divmod(13,5) | integer division by zero |
error | returns FALSE with warning | raises ZeroDivisionError | raises ZeroDivisionError | |||||||||
float division |
13 / 5 | float(13) / 5 # Python 3: 13 / 5 |
13.to_f / 5 or 13.fdiv(5) |
||||||||||||
float division by zero |
returns -Infinity,NaN, or Infinity | ||||||||||||||
power |
2**32 | pow(2,32) | 2**32 | ||||||||||||
sqrt | sqrt(2) | sqrt(2) | import math math.sqrt(2) |
include Math sqrt(2) |
|||||||||||
sqrt -1 |
error unless use Math::Complex in effect | NaN | # raises ValueError: import math math.sqrt(-1) # returns complex float: import cmath cmath.sqrt(-1) |
raises Errno::EDOM | |||||||||||
transcendental functions |
Math::Trig qw( tan asin acos atan); exp log sin cos tan asin acos atan atan2 |
exp log sin cos tan asin acos atan atan2 | from math import exp,log,\ sin,cos,tan,asin,acos,atan,atan2 |
include Math exp log sin cos tan asin acos atan atan2 |
|||||||||||
transcendental constants π and e |
M_PI M_E | import math math.pi math.e |
include Math PI E |
||||||||||||
float truncation |
# cpan -i Number::Format use Number::Format 'round'; use POSIX qw(ceil floor); int($x) round($x,0) ceil($x) floor($x) |
(int)$x round($x) ceil($x) floor($x) |
import math int(x) int(round(x)) math.ceil(x) math.floor(x) |
x.to_i x.round x.ceil x.floor |
|||||||||||
absolute value |
abs($x) | abs($ abs(x) | x.abs | ||||||||||||
integer overflow |
converted to float; use Math::BigInt to create arbitrary length integers | converted to float | becomes arbitrary length integer of type long | becomes arbitrary length integer of typeBignum | |||||||||||
float overflow |
inf | INF | raises OverflowError | Infinity | |||||||||||
rational construction |
Math::BigRat; my $x = Math::BigRat->new("22/7"); |
from fractions import Fraction x = Fraction(22,7) |
require 'rational' x = Rational(22,7) |
||||||||||||
rational decomposition |
$x->numerator(); $x->denominator(); |
x.numerator x.denominator |
x.numerator x.denominator |
||||||||||||
complex construction |
Math::Complex; my $z = 1 + 1.414 * i; |
z = 1 + 1.414j | require 'complex' z = 1 + 1.414.im |
||||||||||||
complex decomposition real and imaginary component,argument,absolute value,conjugate |
Re($z); Im($z); arg($z); abs($z); ~$z; |
import cmath z.real z.imag cmath.phase(z) abs(z) z.conjugate() |
z.real z.imag z.arg z.abs z.conj |
||||||||||||
random number uniform integer,uniform float,normal float |
int(rand() * 100) rand() none |
rand(0,99) lcg_value() none |
import random random.randint(0,99) random.random() random.gauss(0,1) |
rand(100) rand none |
|||||||||||
random seed set,get,restore |
srand 17; my $seed = srand; srand($seed); |
srand(17); none |
import random random.seed(17) seed = random.getstate() random.setstate(seed) |
srand(17) seed = srand srand(seed) |
|||||||||||
bit operators |
<< >> & | ^ ~ | << >> & | ^ ~ | |||||||||||||
binary,octal,and hex literals | 0b101010 052 0x2a |
0b101010 052 0x2a |
|||||||||||||
radix convert integer to and from string with radix |
# cpan -i Math::BaseCalc use Math::BaseCalc; $c = new Math::BaseCalc( digits => [0..6]); $c->to_base(42); $c->from_base("60"); |
base_convert("42",10,7); base_convert("60",7,10); |
none int("60",136); padding:0.3em 0.7em"> 42.to_s(7) "60".to_i(7) |
||||||||||||
strings | |||||||||||||||
string type | SCALAR which is also used for numeric types and references | string | str | String | |||||||||||
string literal |
"don't say \"no\"" 'don\'t say "no"' |
'don\'t say "no"' "don't say \"no\"" "don't " 'say "no"' '''don't say "no"''' """don't say "no\"""" |
"don't say \"no\"" 'don\'t say "no"' "don't " 'say "no"' |
||||||||||||
newline in literal |
'first line second line' "first line second line" |
triple quote literals only: '''first line second line''' """first line second line""" |
'first line second line' "first line second line" |
||||||||||||
literal escapes |
double quoted: \a \b \cx \e \f \n \r \t \xhh \x{hhhh} \ooo\o{ooo} single quoted: \' \\ |
double quoted: \f \n \r \t \v \xhh \$ \" \\ \ooo single quoted: \' \\ |
single and double quoted: \newline \\ \' \" \a \b \f \n \r \t \v \ooo\xhh Python 3: \uhhhh \Uhhhhhhhh |
double quoted: \a \b \cx \e \f \n \r \s \t \v \xhh \ooo\uhhhh \u{hhhhh} single quoted: \' \\ |
|||||||||||
custom delimiters | $s1 = q(lorem ipsum); my $s2 = qq($s1 dolor sit amet); |
s1 = %q(lorem ipsum) s2 = %Q(#{s1} dolor sit amet) |
|||||||||||||
here document |
$word = "amet"; $s = <<EOF; lorem ipsum dolor sit $word EOF |
word = "amet"; $s = <<<EOF lorem ipsum dolor sit $word EOF; |
word = "amet" s = <<EOF lorem ipsum dolor sit #{word} EOF |
||||||||||||
variable interpolation |
$count = 3; my $item = "ball"; print "$count ${item}s\n"; |
count = 3; $item = "ball"; echo "$count ${item}s\n"; |
count = 3 item = 'ball' print('{count} {item}s'.format( **locals())) |
count = 3 item = "ball" puts "#{count} #{item}s" |
|||||||||||
expression interpolation | '1 + 1 = {}'.format(1 + 1) | "1 + 1 = #{1 + 1}" | |||||||||||||
format |
my $fmt = "lorem %s %d %f"; sprintf($fmt, "ipsum",13,3.7) |
fmt = "lorem %s %d %f"; sprintf($fmt,3.7); |
'lorem %s %d %f' % ('ipsum',3.7) fmt = 'lorem {0} {1} {2}' fmt.format('ipsum',136); padding:0.3em 0.7em"> "lorem %s %d %f" % ["ipsum",3.7] |
||||||||||||
are strings mutable? | $s = "bar"; $s2 = $s; # sets s to "baz"; s2 is unchanged: $s =~ s/r/z/; |
s = "bar"; $s2 = $s; # sets s to "baz"; s2 is unchanged: $s[2] = "z"; |
no | s = "bar" s2 = s # sets s and s2 to "baz": s[2] = "z" |
|||||||||||
copy string | $s2 = $s; | s; | s = "bar" s2 = s.clone # s2 is not altered: s[2] = "z" |
||||||||||||
concatenate |
$s = "Hello,"; my $s2 = $s . "World!"; |
s = "Hello,"; $s . "World!"; |
s = 'Hello,' s2 = s + 'World!' # juxtaposition can be used to # concatenate literals: s2 = 'Hello,' "World!" |
s = "Hello," s2 = s + "World!" # juxtaposition can be used to # concatenate literals: s2 ="Hello," 'World!' |
|||||||||||
replicate |
$hbar = "-" x 80; | hbar = str_repeat("-",80); | hbar = '-' * 80 | hbar = "-" * 80 | |||||||||||
translate case to upper,to lower |
uc("lorem") lc("LOREM") |
strtoupper("lorem") strtolower("LOREM") |
'lorem'.upper() 'LOREM'.lower() |
"lorem".upcase "LOREM".downcase |
|||||||||||
capitalize string,words |
# cpan -i Text::Autoformat use Text::Autoformat; ucfirst("lorem") autoformat("lorem ipsum", {case => 'title'}) |
ucfirst("lorem") ucwords("lorem ipsum") |
import string 'lorem'.capitalize() string.capwords('lorem ipsum') |
"lorem".capitalize none |
|||||||||||
trim both sides,left,right |
# cpan -i Text::Trim use Text::Trim; trim " lorem " ltrim " lorem" rtrim "lorem " |
trim(" lorem ") ltrim(" lorem") rtrim("lorem ") |
' lorem '.strip() ' lorem'.lstrip() 'lorem '.rstrip() |
" lorem ".strip " lorem".lstrip "lorem ".rstrip |
|||||||||||
pad on right,on left,centered |
# cpan -i Text::Format use Text::Format; sprintf("%-10s", "lorem") sprintf("%10s", "lorem") $text = Text::Format->new(columns => 10); $text->center("lorem"); |
str_pad("lorem",10) str_pad("lorem", " ", STR_PAD_LEFT) str_pad("lorem", STR_PAD_BOTH) |
'lorem'.ljust(10) 'lorem'.rjust(10) 'lorem'.center(10) |
"lorem".ljust(10) "lorem".rjust(10) "lorem".center(10) |
|||||||||||
number to string |
"value: " . 8 | 'value: ' + str(8) | "value: " + 8.to_s | ||||||||||||
string to number |
7 + "12" 73.9 + ".037" |
7 + int('12') 73.9 + float('.037') |
7 + "12".to_i 73.9 + ".037".to_f |
||||||||||||
join |
join(" ", qw(do re mi fa)) | a = ["do", "re", "mi", "fa"]; implode(" ",136); padding:0.3em 0.7em"> ' '.join(['do', 're', 'mi', 'fa']) # raises TypeError: ' '.join([1,136); padding:0.3em 0.7em"> %w(do re mi fa).join(' ') # implicitly converted to strings: [1,3].join(' ') |
|||||||||||||
split |
split(/\s+/, "do re mi fa") | explode(" ",136); padding:0.3em 0.7em"> 'do re mi fa'.split() | "do re mi fa".split | ||||||||||||
split in two |
"do re mi fa",2) | preg_split('/\s+/',136); padding:0.3em 0.7em"> 'do re mi fa'.split(None,136); padding:0.3em 0.7em"> "do re mi fa".split(/\s+/,2) | |||||||||||||
split and keep delimiters | split(/(\s+)/,136); padding:0.3em 0.7em"> preg_split('/(\s+)/', NULL, PREG_SPLIT_DELIM_CAPTURE) |
re.split('(\s+)', 'do re mi fa') | "do re mi fa".split(/(\s+)/) | ||||||||||||
length |
length("lorem") | strlen("lorem") | len('lorem') | "lorem".length "lorem".size |
|||||||||||
index of substring first,last |
# returns -1 if not found: index("lorem ipsum", "ipsum") rindex("do re re", "re") |
# returns FALSE if not found: strpos("do re re", "re") strrpos("do re re",136); padding:0.3em 0.7em"> # raises ValueError if not found: 'do re re'.index('re') 'do re re'.rindex('re') # returns -1 if not found: 'do re re'.find('re') 'do re re'.rfind('re') |
# returns nil if not found: "do re re".index("re") "do re re".rindex("re") |
||||||||||||
extract substring by start and length,by start and end,by successive starts |
substr("lorem ipsum",6,5) none none |
substr("lorem ipsum",136); padding:0.3em 0.7em"> none none 'lorem ipsum'[6:11] |
"lorem ipsum"[6,5] "lorem ipsum"[6..10] "lorem ipsum"[6...11] |
||||||||||||
extract character | # can't use index notation with # strings: substr("lorem ipsum",136); padding:0.3em 0.7em"> # Syntax error to use index notation # directly on string literal: $s = "lorem ipsum"; $s[6]; |
'lorem ipsum'[6] | "lorem ipsum"[6] | ||||||||||||
chr and ord |
chr(65) ord("A") |
chr(65) ord("A") |
chr(65) ord('A') |
65.chr "A".ord |
|||||||||||
to array of characters | split(//, "abcd") | str_split("abcd") | list('abcd') | "abcd".split("") | |||||||||||
translate characters |
$s = "hello"; $s =~ tr/a-z/n-za-m/; |
ins = implode(range("a", "z")); $outs = substr($ins,13) . substr($"hello",63)">outs) |
from string import lowercase as ins from string import maketrans outs = ins[13:] + ins[:13] 'hello'.translate(maketrans(ins,outs)) |
"hello".tr("a-z", "n-za-m") | |||||||||||
delete characters | $s = "disemvowel me"; $s =~ tr/aeIoU//d; |
vowels = str_split("aeIoU"); $s = "disemvowel me"; $s = str_replace($vowels, "",63)">s); |
"disemvowel me".translate(None, "aeIoU") | "disemvowel me".delete("aeIoU") | |||||||||||
@L_403_214@ | $s = "too much space"; $s =~ tr/ //s; |
s = "too much space"; $s = = preg_replace('/(\s)+/', '\1',136); padding:0.3em 0.7em"> re.sub('(\s)+',r'\1', 'too much space') |
"too much space".squeeze(" ") | ||||||||||||
regular expressions | |||||||||||||||
literal,custom delimited literal | /lorem|ipsum/ qr(/etc/hosts) |
'/lorem|ipsum/' '(/etc/hosts)' |
re.compile('lorem|ipsum') none |
/lorem|ipsum/ %r(/etc/hosts) |
|||||||||||
character class abbreviations | . \d \D \h \H \s \S \v \V \w \W | . \d \D \s \S \w \W | . \d \D \h \H \s \S \w \W | ||||||||||||
anchors |
^ $ \A \b \B \z \Z | ^ $ \A \b \B \Z | ^ $ \A \b \B \z \Z | ||||||||||||
match test |
if ($s =~ /1999/) { print "party!\n"; } |
if (preg_match('/1999/',63)">s)) { echo "party!\n"; } |
if re.search('1999',s): print('party!') |
if /1999/.match(s) puts "party!" end |
|||||||||||
case insensitive match test | "Lorem" =~ /lorem/i | preg_match('/lorem/i', "Lorem") | re.search('lorem', 'Lorem',re.I) | /lorem/i.match("Lorem") | |||||||||||
modifiers |
i m s p x | e i m s x | re.I re.M re.S re.X | i o m x | |||||||||||
substitution |
my $s = "do re mi mi mi"; $s =~ s/mi/ma/g; |
s = "do re mi mi mi"; $s = preg_replace('/mi/', "ma",63)">s = 'do re mi mi mi' s = re.compile('mi').sub('ma',s) |
s = "do re mi mi mi" s.gsub!(/mi/, "ma") |
||||||||||||
match,prematch,postmatch |
if ($s =~ /\d{4}/p) { $match = ${^MATCH}; $prematch = ${^PREMATCH}; $postmatch = ${^POSTMATCH}; } |
m = re.search('\d{4}',s) if m: match = m.group() prematch = s[0:m.start(0)] postmatch = s[m.end(0):len(s)] |
m = /\d{4}/.match(s) if m match = m[0] prematch = m.pre_match postmatch = m.post_match end |
||||||||||||
group capture |
$rx = qr/(\d{4})-(\d{2})-(\d{2})/; "2010-06-03" =~ $rx; ($yr,$mo,$dy) = ($1,$2,$3); |
s = "2010-06-03"; $rx = '/(\d{4})-(\d{2})-(\d{2})/'; preg_match($rx,63)">s,63)">m); list($_,63)">yr,63)">mo,63)">dy) = $m; |
rx = '(\d{4})-(\d{2})-(\d{2})' m = re.search(rx, '2010-06-03') dy = m.groups() |
rx = /(\d{4})-(\d{2})-(\d{2})/ m = rx.match("2010-06-03") yr,mo,dy = m[1..3] |
|||||||||||
named group capture | $s = "foo.txt"; $s =~ /^(?<file>.+)\.(?<suffix>.+)$/; $+{"file"} $+{"suffix"} |
s = "foo.txt"; $rx = '/^(?P<file>.+)\.(?P<suffix>.+)$/'; preg_match($m); $m["file"] $m["suffix"] |
rx = '^(?P<file>.+)\.(?P<suffix>.+)$' ''foo.txt') m.groupdict()['file'] m.groupdict()['suffix'] |
rx = /^(?<file>.+)\.(?<suffix>.+)$/ m = rx.match('foo.txt') m["file"] m["suffix"] |
|||||||||||
scan |
s = "dolor sit amet"; @a = $s =~ m/\w+/g; |
s = "dolor sit amet"; preg_match_all('/\w+/',63)">m); $a = $m[0]; |
s = 'dolor sit amet' a = re.findall('\w+',136); padding:0.3em 0.7em"> a = "dolor sit amet".scan(/\w+/) |
||||||||||||
backreference in match and substitution | "do do" =~ /(\w+) \1/ my $s = "do re"; $s =~ s/(\w+) (\w+)/$2 $1/; |
preg_match('/(\w+) \1/', "do do") $s = "do re"; $rx = '/(\w+) (\w+)/'; $s = preg_replace($'\2 \1',136); padding:0.3em 0.7em"> none rx = re.compile('(\w+) (\w+)') rx.sub(r'\2 \1', 'do re') |
/(\w+) \1/.match("do do") "do re".sub(/(\w+) (\w+)/, '\2 \1') |
||||||||||||
recursive regex | /\(([^()]*|(?R))\)/ | '/\(([^()]*|($R))\)/' | /(?<foo>\(([^()]*|\g<foo>)*\))/ | ||||||||||||
dates and time | |||||||||||||||
date/time type | Time::Piece if use Time::Piece in effect,otherwise tm array | DateTime | datetime.datetime | Time | |||||||||||
current date/time | Time::Piece; my $t = localtime(time); my $utc = gmtime(time); |
t = new DateTime("now"); $utc_tmz = new DateTimeZone("UTC"); $utc = new DateTime("now",63)">utc_tmz); |
import datetime t = datetime.datetime.now() utc = datetime.datetime.utcnow() |
t = Time.now utc = Time.now.utc |
|||||||||||
to unix epoch,from unix epoch | Time::Local; use epoch = timelocal($t); my $t2 = localtime(1304442000); |
epoch = $t->getTimestamp(); $t2 = new DateTime(); $t2->setTimestamp(1304442000); |
from datetime import datetime as dt epoch = int(t.strftime("%s")) t2 = dt.fromtimestamp(1304442000) |
epoch = t.to_i t2 = Time.at(1304442000) |
|||||||||||
current unix epoch | $epoch = time; | epoch = time(); | epoch = int(t.strftime("%s")) | epoch = Time.now.to_i | |||||||||||
strftime | Time::Piece; $t = localtime(time); $fmt = "%Y-%m-%d %H:%M:%S"; print $t->strftime($fmt); |
strftime("%Y-%m-%d %H:%M:%S",63)">epoch); date("Y-m-d H:i:s",63)">epoch); $t->format("Y-m-d H:i:s"); |
t.strftime('%Y-%m-%d %H:%M:%S') | t.strftime("%Y-%m-%d %H:%M:%S") | |||||||||||
default format example | Tue Aug 23 19:35:19 2011 | no default string representation | 2011-08-23 19:35:59.411135 | 2011-08-23 17:44:53 -0700 | |||||||||||
strptime | Time::Piece; $s = "2011-05-03 10:00:00"; $fmt = "%Y-%m-%d %H:%M:%S"; $t = Time::Piece->strptime($s,$fmt); |
fmt = "Y-m-d H:i:s"; $s = "2011-05-03 10:00:00"; $t = DateTime::createFromFormat($ $ from datetime import datetime s = '2011-05-03 10:00:00' fmt = '%Y-%m-%d %H:%M:%S' t = datetime.strptime(s,fmt) |
require 'date' s = "2011-05-03 10:00:00" fmt = "%Y-%m-%d %H:%M:%S" t = Date.strptime(s,fmt).to_time |
||||||||||||
parse date w/o format | # cpan -i Date::Parse use Date::Parse; $epoch = str2time("July 7,1999"); |
epoch = strtotime("July 7,136); padding:0.3em 0.7em"> # pip install python-dateutil import dateutil.parser s = 'July 7,1999' t = dateutil.parser.parse(s) |
require 'date' s = "July 7,1999" t = Date.parse(s).to_time |
||||||||||||
result of date subtraction | Time::Seconds object if use Time::Piece in effect; not meaningful to subtract tm arrays | DateInterval object if diff method used: $then = DateTime::createFromFormat($s); $now = new DateTime("now"); $interval = $now->diff($then); |
datetime.timedelta object use total_seconds() method to convert to float representing difference in seconds |
Float containing time difference in seconds | |||||||||||
add time duration | Time::Seconds; $now = localtime(time); $now += 10 * ONE_MINUTE() + 3; |
now->add(new DateInterval("PT10M3S"); | delta = datetime.timedelta( minutes=10, seconds=3) t = datetime.datetime.now() + delta |
require 'date/delta' s = "10 min,3 s" delta = Date::Delta.parse(s).in_secs t = Time.now + delta |
|||||||||||
local timezone | Time::Piece has local timezone if created with localtime and UTC timezone if created with gmtime; tm arrays have no timezone or offset info | DateTime objects can be instantiated without specifying the timezone if a default is set: $s = "America/Los_Angeles"; date_default_timezone_set($ a datetime object has no timezone information unless a tzinfo object is provided when it is created |
if no timezone is specified the local timezone is used | ||||||||||||
arbitrary timezone | # pip install pytz import pytz import datetime tmz = pytz.timezone('Asia/Tokyo') utc = datetime.datetime.utcnow() utc_dt = datetime.datetime( *utc.timetuple()[0:5], tzinfo=pytz.utc) jp_dt = utc_dt.astimezone(tmz) |
# gem install tzinfo require 'tzinfo' tmz = TZInfo::Timezone.get("Asia/Tokyo") jp_time = tmz.utc_to_local(Time.now.utc) |
|||||||||||||
timezone name; offset from UTC; is daylight savings? | # cpan -i DateTime use DateTime; use DateTime::TimeZone; $dt = DateTime->now(); $tz = DateTime::TimeZone->new( name=>"local"); $tz->name; $tz->offset_for_datetime($dt) / 3600; $tz->is_dst_for_datetime($dt); |
tmz = date_timezone_get($t); timezone_name_get($tmz); date_offset_get($t) / 3600; $t->format("I"); |
import time tm = time.localtime() time.tzname[tm.tm_isdst] (time.timezone / -3600) + tm.tm_isdst tm.tm_isdst |
t.zone t.utc_offset / 3600 t.dst? |
|||||||||||
microseconds | Time::HiRes qw(gettimeofday); ($sec,$usec) = gettimeofday; |
frac,63)">sec) = explode(" ", microtime()); $usec = $frac * 1000 * 1000; |
t.microsecond | t.usec | |||||||||||
sleep | # a float argument will be truncated # to an integer: sleep 1; |
# a float argument will be truncated # to an integer: sleep(1); |
import time time.sleep(0.5) |
sleep(0.5) | |||||||||||
timeout | eval { $SIG{ALRM}= sub {die "timeout!";}; alarm 5; sleep 10; }; alarm 0; |
use set_time_limit to limit execution time of the entire script; use stream_set_timeoutto limit time spent reading from a stream opened with fopen or fsockopen | import signal,time class Timeout(Exception): pass def timeout_handler(signo,fm): raise Timeout() signal.signal(signal.SIGALRM, timeout_handler) try: signal.alarm(5) time.sleep(10) except Timeout: pass signal.alarm(0) |
require 'timeout' begin Timeout.timeout(5) do sleep(10) end rescue Timeout::Error end |
|||||||||||
arrays | |||||||||||||||
literal | @a = (1,3,4); | # older Syntax: $a = array(1,4] |
a = [1,4] | ||||||||||||
quote words |
@a = qw(do re mi); | a = %w(do re mi) | |||||||||||||
size |
$#a + 1 or scalar(@a) |
count($ len(a) | a.size a.length # same as size |
||||||||||||
empty test |
!@a | !$a | not a | NoMethodError if a is nil: a.empty? |
|||||||||||
lookup |
$a[0] # returns last element: $a[-1] |
a[0] # PHP uses the same type for arrays and # dictionaries; indices can be negative # integers or strings |
a[0] # returns last element: a[-1] |
a[0] # returns last element: a[-1] |
|||||||||||
update |
$a[0] = "lorem"; | a[0] = "lorem"; | a[0] = 'lorem' | a[0] = "lorem" | |||||||||||
out-of-bounds behavior | @a = (); # evaluates as undef: $a[10]; # increases array size to 11: $a[10] = "lorem"; |
a = []; # evaluates as NULL: $a[10]; # increases array size to one: $a[10] = "lorem"; |
a = [] # raises IndexError: a[10] # raises IndexError: a[10] = 'lorem' |
a = [] # evaluates as nil: a[10] # increases array size to 11: a[10] = "lorem" |
|||||||||||
index of element | List::Util 'first'; @a = qw(x y z w); $i = first {$a[$_] eq "y"} (0..$#a); |
a = ["x", "y", "z", "w"]; $i = array_search("y",63)">a); |
a = ['x', 'y', 'z', 'w'] i = a.index('y') |
a = %w(x y z w) i = a.index("y") |
|||||||||||
slice by endpoints,by length |
# select 3rd and 4th elements: @a[2..3] splice(@a,136); padding:0.3em 0.7em"> # select 3rd and 4th elements: none array_slice($ # select 3rd and 4th elements: a[2:4] a[2:2 + 2] |
# select 3rd and 4th elements: a[2..3] a[2,2] |
|||||||||||||
slice to end |
@a[1..$#a] | array_slice($ a[1:] | a[1..-1] | ||||||||||||
manipulate back |
@a = (6,8); push @a,9; pop @a; |
a = [6,8]; array_push($a[] = 9; # same as array_push array_pop($ a = [6,8] a.push(9) a << 9 # same as push a.pop |
|||||||||||||
@L_841_301@manipulate front |
unshift @a,5; shift @a; |
array_shift($ a.unshift(5) a.shift |
|||||||||||||
concatenate | @a2 = (@a,(4,5,6)); push @a,6); |
a2 = array_merge($a = array_merge($a2 = a + [4,6] a.extend([4,6]) |
replicate | @a = (undef) x 10; | a = [None] * 10 a = [None for i in range(0,10)] |
a = [nil] * 10 a = Array.new(10,63)">nil) |
|||||||||
copy address copy,shallow copy,deep copy |
Storable 'dclone' my @a = (1,[3,4]); my $a2 = \@a; my @a3 = @a; my @a4 = @{dclone(\@a)}; |
a2 =& $a; none $a4 = $a; |
import copy a2 = a a3 = list(a) a4 = copy.deepcopy(a) |
Marshal.load(Marshal.dump(a)) | |||||||||||
arrays as function arguments | each element passed as separate argument; use reference to pass array as single argument | parameter contains deep copy | parameter contains address copy | parameter contains address copy | |||||||||||
iterate over elements |
for $i (1,3) { print "$i\n" } | foreach ([1,3] as $i) { echo "$i\n"; } |
for i in [1,3]: print(i) |
iterate over indices and elements | none; use range iteration from 0 to $#a and use index to look up value in the loop body | "mi" "fa"]; foreach ($a as $i => $s) { echo "$s at index $i\n"; } |
a = ['do', 'fa'] for i,s in enumerate(a): print('%s at index %d' % (s,i)) |
a = %w(do re mi fa) a.each_with_index do |s,i| puts "#{s} at index #{i}" end |
|||||||
iterate over range | $i (1..1_000_000) { code } |
not space efficient; use C-style for loop | # use range() in Python 3: for i in xrange(1,1000001): code |
(1..1_000_000).each do |i| code end |
|||||||||||
instantiate range as array | @a = 1..10; | a = range(1,63)">a = range(1,11) Python 3: a = list(range(1,11)) |
a = (1..10).to_a | ||||||||||||
reverse non-destructive,in-place |
reverse @a; @a = reverse @a; |
a); $a = array_reverse($ a.reverse a.reverse! |
|||||||||||||
sort non-destructive, in-place, custom comparision |
@a = qw(b A a B); sort @a; @a = sort @a; sort { lc($a) cmp lc($b) } @a; |
a = ["b", "A", "a", "B"]; none sort($a); none,but usort sorts in place |
a = ['b', 'A', 'a', 'B'] sorted(a) a.sort() # custom binary comparision # removed from Python 3: a.sort(key=str.lower) |
a = %w(b A a B) a.sort a.sort! a.sort do |x,y| x.downcase <=> y.downcase end |
|||||||||||
dedupe non-destructive,205)">List::MoreUtils 'uniq'; my @a = (1,3); my @a2 = uniq @a; @a = uniq @a; |
a2 = array_unique($a = array_unique($a2 = list(set(a)) a = list(set(a)) |
membership |
7 ~~ @a | in_array(7,136); padding:0.3em 0.7em"> 7 in a | a.include?(7) | ||||||||||
intersection |
b = [2,4] array_intersect($b) |
{1,2} & {2,4} | union |
a1 = [1,63)">a2 = [2,4]; array_unique(array_merge($a1,63)">a2)) |
relative complement,symmetric difference | a2 = [2]; array_values(array_diff($a2)) none |
require 'set' [1,3] - [2] Set[1,2] ^ Set[2,136); padding:0.3em 0.7em"> map |
map { $_ * $_ } (1,3) | array_map(function ($x) { return $x * $x; },[1,136); padding:0.3em 0.7em"> map(lambda x: x * x,3]) # or use list comprehension: [x * x for x in [1,3]] |
filter |
grep { $_ > 1 } (1,136); padding:0.3em 0.7em"> array_filter([1,3], function ($x>1; }) |
filter(lambda x: x > 1,3]) # or use list comprehension: [x for x in [1,3] if x > 1] |
reduce |
List::Util 'reduce'; reduce { $x + $y } 0,(1,136); padding:0.3em 0.7em"> array_reduce([1, function($y) { return $x + $y; },0) |
# import needed in Python 3 only from functools import reduce reduce(lambda x,y: x+y,3].inject(0) { |m,o| m+o } |
universal and existential tests |
# cpan -i List::MoreUtils use List::MoreUtils qw(all any); all { $_ % 2 == 0 } (1,4) any { $_ % 2 == 0 } (1,4) |
use array_filter | all(i % 2 == 0 for i in [1,4]) any(i % 2 == 0 for i in [1,4]) |
shuffle and sample | List::Util 'shuffle'; @a = (1,4); shuffle(@a); none |
a); array_rand($ from random import shuffle,sample zip |
List::MoreUtils 'zip'; @nums = (1,3); @lets = qw(a b c); # flat array of 6 elements: @a = zip @nums, @lets; |
# array of 3 pairs: $a = array_map(NULL, [1, ["a", "b", "c"]); |
# array of 3 pairs: a = zip([1,['a', 'b', 'c']) |
# array of 3 pairs: a = [1,3].zip(["a", "c"]) |
|||||
dictionaries | |||||||||||||||
%d = ( "t" => 1, "f" => 0 ); # barewords permitted in front of => # under 'use strict' | d = ["t" => 1, "f" => 0]; # older syntax: $d = array("t" => 1, "f" => 0); |
d = { 't':1, 'f':0 } | d = { "t" => 1, "f" => 0 } | ||||||||||||
scalar(keys %d) | d) | len(d) | d.size d.length # same as size |
||||||||||||
$d{"t"} # barewords permitted inside { } # under 'use strict' |
d["t"] | d['t'] | d["t"] | ||||||||||||
out-of-bounds behavior |
%d = (); evaluates as undef: $d{"lorem"}; adds key/value pair: $d{"lorem"} = "ipsum"; |
d = []; evaluates as NULL: $d["lorem"]; adds key/value pair: $d["lorem"] = "ipsum"; |
d = {} raises KeyError: d['lorem'] adds key/value pair: d['lorem'] = 'ipsum' |
d = {} evaluates as nil: d["lorem"] adds key/value pair: d["lorem"] = "ipsum" |
|||||||||||
is key present |
exists $d{"y"} | array_key_exists("y",63)">d); | 'y' in d | d.has_key?("y") | |||||||||||
delete entry | %d = ( 1 => "t",0 => "f" ); delete $d{1}; |
d = [1 => "t",0 => "f"]; unset($d[1]); |
d = {1: True,0: False} del d[1] |
d = {1 => true,0 => false} d.delete(1) |
|||||||||||
from array of pairs,from even length array | "a","b","c"); %d = @a; |
a = [[1,'a'],[2,'b'],'c']] d = dict(a) 'a','b','c'] d = dict(zip(a[::2],a[1::2])) |
a = [[1,"a"],"b"],"c"]] d = Hash[a] a = [1,"c"] d = Hash[*a] |
||||||||||||
merge | %d1 = (a=>1, b=>2); %d2 = (b=>3, c=>4); %d1 = (%d1, %d2); |
d1 = ["a"=>1, "b"=>2]; $d2 = ["b"=>3, "c"=>4]; $d1 = array_merge($d1,63)">d2); |
d1 = {'a':1, 'b':2} d2 = {'b':3, 'c':4} d1.update(d2) |
d1 = {"a"=>1, "b"=>2} d2 = {"b"=>3, "c"=>4} d1.merge!(d2) |
|||||||||||
invert | %to_num = (t=>1, f=>0); %to_let = reverse %to_num; |
to_num = ["t"=>1, "f"=>0]; $to_let = array_flip($to_num); |
to_num = {'t':1, 'f':0} # dict comprehensions added in 2.7: to_let = {v:k for k,v in to_num.items()} |
to_num = {"t"=>1, "f"=>0} to_let = to_num.invert |
|||||||||||
iteration |
while (($k,$v) = each %d) { code } |
foreach ($d as $k => $v) { code } |
for k,v in d.iteritems(): code Python 3: for k,v in d.items(): code |
d.each do |k,v| code end |
|||||||||||
keys and values as arrays | keys %d values %d |
array_keys($d) array_values($ d.keys() d.values() Python 3: list(d.keys()) list(d.values()) |
d.keys d.values |
||||||||||||
sort by values | foreach $k (sort { $d{$a} <=> $b} } keys %d) { print "$k: $d{$k}\n"; } |
asort($d); foreach ($d as $v) { print "$k: $v\n"; } |
from operator import itemgetter pairs = sorted(d.iteritems(), key=itemgetter(1)) for k,v in pairs: print('{}: {}'.format(k,v)) |
d.sort_by {|k,v| v}.each do |k,v| puts "#{k}: #{v}" end |
|||||||||||
default value,computed value | my %counts; $counts{'foo'} += 1 define a tied hash for computed values and defaults other than zero or empty string |
counts = []; $counts['foo'] += 1; extend ArrayObject for computed values and defaults other than zero or empty string. |
from collections import defaultdict counts = defaultdict(lambda: 0) counts['foo'] += 1 class Factorial(dict): def __missing__(self,k): if k > 1: return k * self[k-1] else: return 1 factorial = Factorial() |
counts = Hash.new(0) counts['foo'] += 1 factorial = Hash.new do |h,k| k > 1 ? k * h[k-1] : 1 end |
|||||||||||
functions | |||||||||||||||
define function | sub add3 { $_[0] + $_[1] + $_[2] } sub add3 { my ($x1,63)">$x2,63)">$x3) = @_; $x1 + $x2 + $x3; } |
function add3($x1,63)">x2,63)">x3) { return $x1 + $x2 + $x3; } |
def add3(x1,x2,x3): return x1 + x2 + x3 |
x1 + x2 + x3 end # parens are optional and customarily # omitted when defining functions # with no parameters |
|||||||||||
invoke function | add3(1,3); # parens are optional: add3 1,3; |
# function names are case insensitive: ADD3(1,3) # parens are optional: add3 1,136); padding:0.3em 0.7em"> apply function to array |
@a = (2,3); add3(1, @a); # arrays are always expanded when used # as arguments |
"add3",63)">a = [2,3] add3(1,*a) # splat operator can only be used once # and must appear after other # unnamed arguments |
a = [2,*a) # splat operator can be used multiple # times and can appear before regular # arguments |
||||||||||
missing argument behavior |
set to undef | set to NULL with warning | raises TypeError if number of arguments doesn't match function arity | raises ArgumentError if number of arguments doesn't match function arity | |||||||||||
default argument |
my_log { my $x = shift; my $base = shift // 10; log($x) / log($base); } my_log(42); my_log(42, exp(1)); |
my_log($base=10) { return log($x) / log($base); } my_log(42); my_log(42, M_E); |
import math def my_log(x,base=10): return math.log(x) / math.log(base) my_log(42) my_log(42,math.e) |
Math.log(x) / Math.log(base) end my_log(42) my_log(42, Math::E) |
|||||||||||
variable number of arguments | first_and_last { if ( @_ >= 1 ) { print "first: $_[0]\n"; } if ( @_ >= 2 ) { print "last: $_[-1]\n"; } } |
first_and_last() { $arg_cnt = func_num_args(); if ($arg_cnt >= 1) { $n = func_get_arg(0); echo "first: " . $n . "\n"; } if ($arg_cnt >= 2) { $a = func_get_args(); $n = $a[$arg_cnt-1]; echo "last: " . $n . "\n"; } } |
first_and_last(*a): if len(a) >= 1: print('first: ' + str(a[0])) if len(a) >= 2: print('last: ' + str(a[-1])) |
first_and_last(*a) if a.size >= 1 puts "first: #{a[0]}" end if a.size >= 2 puts "last: #{a[-1]}" end end |
|||||||||||
named parameters |
fequal(x,eps=0.01): return abs(x - y) < eps fequal(1.0,1.001) fequal(1.0,1.001,eps=0.1**10) |
eps = opts[:eps] || 0.01 (x - y).abs < eps end fequal(1.0, :eps=>0.1**10) # Ruby 2.0: def fequals(x, eps: 0.01) (x - y).abs < eps end fequals(1.0,1.001) fequals(1.0, eps: 0.1**10) |
|||||||||||||
pass number or string by reference |
foo { $_[0] += 1; $_[1] .= "ly"; } my $n = 7; my $s = "hard"; foo($n,$s); |
foo(&$y) { $x += 1; $y .= "ly"; } $n = 7; $s = "hard"; foo($n,136); padding:0.3em 0.7em"> not possible |
not possible | ||||||||||||
pass array or dictionary by reference |
foo { $_[0][2] = 5; $_[1]{"f"} = -1; } my @a = (1,3); my %d = ("t"=> 1, "f" => 0); foo(\@a,\%d); |
x[2] = 5; $y["f"] = -1; } $d = ["t"=>1, "f"=>0]; foo($foo(x,y): x[2] = 5 y['f'] = -1 d = {'t':1, 'f':0} foo(a,d) |
x[2] = 5 y["f"] = -1 end a = [1,3] d = {"t"=> 1, "f" => 0 } foo(a,d) |
||||||||||||
return value |
return arg or last expression evaluated | return arg or NULL | return arg or None | return arg or last expression evaluated | |||||||||||
multiple return values |
first_and_second { return ($_[0], $_[1]); } @a = (1,3); ($x,$y) = first_and_second(@a); |
first_and_second(&$a) { return [$a[0],63)">a[1]]; } $y) = first_and_second($a); |
first_and_second(a): return a[0],a[1] y = first_and_second([1,205)">first_and_second(a) return a[0],a[1] end x,y = first_and_second([1,3]) |
||||||||||||
lambda declaration |
$sqr = sub { $_[0] * $_[0] } | sqr = function ($x) { return $x; }; |
# body must be an expression: sqr = lambda x: x * x |
sqr = lambda { |x| x * x } | |||||||||||
lambda invocation | $sqr->(2) | sqr(2) | sqr(2) | sqr.call(2) or sqr[2] |
|||||||||||
function as value |
$func = \&add; | func = "add"; | func = add | func = lambda {|*args| add(*args)} | |||||||||||
@L_301_399@function with private state | feature state; sub counter { state $i = 0; ++$i; } print counter() . "\n"; |
counter() { static $i = 0; return ++$i; } echo counter(); |
# state not private: def counter(): counter.i += 1 return counter.i counter.i = 0 print(counter()) |
none | |||||||||||
closure | make_counter { my $i = 0; return sub { ++$i }; } my $nays = make_counter; print $nays->() . "\n"; |
make_counter() { $i = 0; return function () use (&$i) { return ++$i; }; } $nays = make_counter(); echo $nays(); |
# Python 3: def make_counter(): i = 0 def counter(): nonlocal i i += 1 return i return counter nays = make_counter() |
make_counter i = 0 return lambda { i +=1; i } end nays = make_counter puts nays.call |
|||||||||||
@L_895_403@@L_662_404@ | # PHP 5.5: function make_counter() { $i = 0; while (1) { yield ++$i; } } $nays = make_counter(); # does not return a value: $nays->next(); # runs generator if generator has not # yet yielded: echo $nays->current(); |
# The itertools library contains # standard generators. # c.f. itertools.count() def make_counter(): i = 0 while True: i += 1 yield i nays = make_counter() print(nays.next()) |
make_counter return Fiber.new do i = 0 while true i += 1 Fiber.yield i end end end nays = make_counter puts nays.resume |
||||||||||||
decorator | logcall(f): def wrapper(*a,**opts): print('calling ' + f.__name__) f(*a,**opts) print('called ' + f.__name__) return wrapper @logcall def square(x): return x * x |
||||||||||||||
operator as function | import operator operator.mul(3,7) a = ['foo', 'bar', 'baz'] operator.itemgetter(2)(a) |
3.*(7) a = ['foo', 'baz'] a.[](2) |
|||||||||||||
execution control | |||||||||||||||
if | if ( 0 == $n ) { print "no hits\n" } elsif ( 1 == $n ) { print "one hit\n" } else { print "$n hits\n" } |
if ( 0 == $n ) { echo "no hits\n"; } elseif ( 1 == $n ) { echo "one hit\n"; } else { echo "$n hits\n"; } |
if 0 == n: print('no hits') elif 1 == n: print('one hit') else: print(str(n) + ' hits') |
if n == 0 puts "no hits" elsif 1 == n puts "one hit" else puts "#{n} hits" end |
|||||||||||
switch | feature 'switch'; given ($n) { when (0) { print "no hits\n"; } when (1) { print "one hit\n"; } default { print "$n hits\n"; } } |
switch ($n) { case 0: echo "no hits\n"; break; case 1: echo "one hit\n"; break; default: echo "$n hits\n"; } |
case n when 0 puts "no hits" when 1 puts "one hit" else puts "#{n} hits" end |
||||||||||||
while |
while ( $i < 100 ) { $i++ } | while ( $i < 100 ) { $i++; } | while i < 100: i += 1 |
while i < 100 do i += 1 end |
|||||||||||
c-style for |
for ( $i=0; $i <= 10; $i++ ) { print "$i\n"; } |
for ($i = 1; $i <= 10; $i++) { echo "$i\n"; } |
break,continue,redo |
last next redo | break continue none | break next redo | |||||||||
control structure keywords | do else elsif for foreach goto if unless until while | case default do else elseif for foreach goto if switch while | elif else for if while | case do else elsif end for loop when while unless until | |||||||||||
what do does | executes following block and returns value of last statement executed | starts body of a do-while loop,a loop which checks the condition after the body is executed | raises NameError unless a value was assigned to it | starts an anonymous block. Also starts the body of a loop,while, or until loop | |||||||||||
statement modifiers |
print "positive\n" if $i > 0; print "nonzero\n" unless $i == 0; |
puts "positive" if i > 0 puts "nonzero" unless i == 0 |
|||||||||||||
exceptions | |||||||||||||||
raise exception | die "bad arg"; | throw new Exception("bad arg"); | raise Exception('bad arg') | # raises RuntimeError raise "bad arg" |
|||||||||||
re-raise exception | try: raise Exception('bam!') except: print('re-raising...') raise |
begin raise "bam!" rescue puts "re-raising…" raise end |
|||||||||||||
catch exception |
eval { risky }; if ($@) { print "risky Failed: $@\n"; } |
try { risky(); } catch (Exception $e) { echo "risky Failed: ", $e->getMessage(), "\n"; } |
try: risky() except: print('risky Failed') |
# catches StandardError begin risky rescue print "risky Failed: " puts $!.message end |
|||||||||||
global variable for last exception | $EVAL_ERROR: $@ $OS_ERROR: $! $CHILD_ERROR: $? |
last exception: sys.exc_info()[1] | last exception: $! backtrace array of exc.: $@ exit status of child: $? |
||||||||||||
define exception | class Bam extends Exception { function __construct() { parent::__construct("bam!"); } } |
class Bam(Exception): def __init__(self): super(Bam, self).__init__('bam!') |
class Bam < Exception def initialize super("bam!") end end |
||||||||||||
catch exception by type | try { throw new Bam; } catch (Bam $e) { echo $ try: raise Bam() except Bam as e: print(e) |
begin raise Bam.new rescue Bam => e puts e.message end |
|||||||||||||
finally/ensure |
acquire_resource() try: risky() finally: release_resource() |
acquire_resource begin risky ensure release_resource end |
|||||||||||||
concurrency | |||||||||||||||
start thread | threads; $func = sub { sleep 10 }; $thr = threads->new($func); |
class sleep10(threading.Thread): def run(self): time.sleep(10) thr = sleep10() thr.start() |
thr = Thread.new { sleep 10 } | ||||||||||||
wait on thread |
$thr->join; | thr.join() | thr.join | ||||||||||||
____________________________________________ | _____________________________________________ | _____________________________________________ |
file handles | files | libraries and namespaces |debugging and profiling | deployment
General
versions used
The versions used for testing code in the reference sheet.
show version
How to get the version.
perl:
Also available in the predefined variable $],or in a different format in $^V and $PERL_VERSION.
PHP:
The function PHPversion() will return the version number as a string.
python:
The following function will return the version number as a string:
import platform platform.python_version()
ruby:
Also available in the global constant RUBY_VERSION.
implicit prologue
Code which examples in the sheet assume to have already been executed.
perl:
We adopt the convention that if an example uses a variable without declaring it,it should be taken to have been prevIoUsly declared with my.
python:
We assume that os, re,and sys are always imported.
Grammar and Invocation
interpreter
The customary name of the interpreter and how to invoke it.
PHP:
PHP -f will only execute portions of the source file within a <?PHP PHP code ?> tag as PHP code. Portions of the source file outside of such tags is not treated as executable code and is echoed to standard out.
If short tags are enabled,then PHP code can also be placed inside <? PHP code ?> and <?= PHP code ?> tags.
<?= PHP code ?> is identical to <?PHP echo PHP code ?>.
repl
The customary name of the repl.
perl:
The Perl REPL perl -de 0 does not save or display the result of an expression. perl -d is the Perl debugger andperl -e runs code provided on the command line.
perl -de 0 does not by default have readline,but it can be added:
PHP:
The PHP -a REPL does not save or display the result of an expression.
python:
The python repl saves the result of the last statement in _.
ruby:
irb saves the result of the last statement in _.
command line program
How to pass the code to be executed to the interpreter as a command line argument.
block delimiters
How blocks are delimited.
perl:
Curly brackets {} delimit blocks. They are also used for:
- hash literal Syntax which returns a reference to the hash: $rh = { 'true' => 1,'false' => 0 }
- hash value lookup: $h{'true'},$rh->{'true'}
- variable name delimiter: $s = "hello"; print "${s}goodbye";
python:
Python blocks begin with a line that ends in a colon. The block ends with the first line that is not indented further than the initial line. Python raises an IndentationError if the statements in the block that are not in a nested block are not all indented the same. Using tabs in Python source code is unrecommended and many editors replace them automatically with spaces. If the Python interpreter encounters a tab,it is treated as 8 spaces.
The python repl switches from a >>> prompt to a … prompt inside a block. A blank line terminates the block.
Colons are also used to separate keys from values in dictionary literals and in sequence slice notation.
ruby:
Curly brackets {} delimit blocks. A matched curly bracket pair can be replaced by the do and end keywords. By convention curly brackets are used for one line blocks.
The end keyword also terminates blocks started by def,96); padding-left:2px; padding-right:1px">class,or module.
Curly brackets are also used for hash literals,and the #{ } notation is used to interpolate expressions into strings.
statement separator
How the parser determines the end of a statement.
perl:
In a script statements are separated by semicolons and never by newlines. However,when using perl -de 0 a newline terminates the statement.
PHP:
Inside braces statements must be terminated by a semicolon. The following causes a parse error:
The last statement inside <?= ?> or <? ?> tags does not need to be semicolon terminated,however. The following code is legal:
python:
Newline does not terminate a statement when:
- inside parens
- inside list [] or dictionary {} literals
Python single quote '' and double quote "" strings cannot contain newlines except as the two character escaped form \n. Putting a newline in these strings results in a Syntax error. There is however a multi-line string literal which starts and ends with three single quotes ''' or three double quotes: """.
A newline that would normally terminate a statement can be escaped with a backslash.
ruby:
Newline does not terminate a statement when:
- inside single quotes '',double quotes "",backticks ``,or parens ()
- after an operator such as + or,that expects another argument
Ruby permits newlines in array [] or hash literals,but only after a comma,or associator =>. Putting a newline before the comma or associator results in a Syntax error.
A newline that would normally terminate a statement can be escaped with a backslash.
source code encoding
How to identify the character encoding for a source code file.
Setting the source code encoding makes it possible to safely use non-ASCII characters in string literals and regular expression literals.
end-of-line comment
How to create a comment that ends at the next newline.
multiple line comment
How to comment out multiple lines.
python:
The triple single quote ''' and triple double quote """ Syntax is a Syntax for string literals.
Variables and Expressions
local variable
How to declare variables which are local to the scope defining region which immediately contain them.
perl:
Variables don't need to be declared unless use strict is in effect.
If not initialized,scalars are set to undef,arrays are set to an empty array,and hashes are set to an empty hash.
Perl can also declare variables with local. These replace the value of a global variable with the same name,if any,for the duration of the enclosing scope,after which the old value is restored.
PHP:
Variables do not need to be declared and there is no Syntax for declaring a local variable. If a variable with no prevIoUs reference is accessed,its value is NULL.
python:
A variable is created by assignment if one does not already exist. If the variable is inside a function or method,then its scope is the body of the function or method. Otherwise it is a global.
ruby:
Variables are created by assignment. If the variable does not have a dollar sign ($) or ampersand (@) as its first character then its scope is scope defining region which most immediately contains it.
A lower case name can refer to a local variable or method. If both are defined,the local variable takes precedence. To invoke the method make the receiver explicit: e.g. self.name. However,outside of class and modules local variables hide functions because functions are private methods in the class Object. Assignment to name will create a local variable if one with that name does not exist,even if there is a method name.
regions which define lexical scope
A list of regions which define a lexical scope for the local variables they contain.
Local variables defined inside the region are only in scope while code within the region is executing. If the language does not have closures,then code outside the region has no access to local variables defined inside the region. If the language does have closures,then code inside the region can make local variables accessible to code outside the region by returning a reference.
A region which is top level hides local variables in the scope which contains it from the code it contains. A region can also be top level if the Syntax requirements of the language prohibit it from being placed inside another scope defining region.
A region is nestable if it can be placed inside another scope defining region,and if code in the inner region can access local variables in the outer region.
perl:
A local variable can be defined outside of any function definition or anonymous block,in which case the scope of the variable is the file containing the source code. In this way Perl resembles Ruby and contrasts with PHP and Python. In PHP and Python,any variable defined outside a function definition is global.
In Perl,when a region which defines a scope is nested inside another,then the inner region has read and write access to local variables defined in the outer region.
Note that the blocks associated with the keywords if, unless, while, until, for,and foreach are anonymous blocks,and thus any my declarations in them create variables local to the block.
PHP:
Only function bodies and method bodies define scope. Function definitions can be nested,but when this is done lexical variables in the outer function are not visible to code in the body of the inner function.
Braces can be used to set off blocks of codes in a manner similar to the anonymous blocks of Perl. However,these braces do not define a scope. Local variables created inside the braces will be visible to subsequent code outside of the braces.
Local variables cannot be created in class bodies.
python:
Only functions and methods define scope. Function definitions can be nested. When this is done,inner scopes have read access to variables defined in outer scopes. Attempting to write (i.e. assign) to a variable defined in an outer scope will instead result in a variable getting created in the inner scope. Python trivia question: what would happen if the following code were executed?
ruby:
The keywords if, case,and until each define a block which is terminated by an end keyword,but none of these blocks have their own scope.
Anonymous functions can be created with the lambda keyword. Ruby anonymous blocks can be provided after a function invocation and are bounded by curly brackets { } or the do and end keywords. Both anonymous functions and anonymous blocks can have parameters which are specified at the start of the block within pipes. Here are some examples:
The scope of the parameters of an anonymous block or anonymous function is local to the block or function body.
It is possible to mark variables as local,even when they are already defined in the containing scope. Such variables are listed inside the parameter pipes,separated from the parameters by a semicolon:
global variable
How to declare and access a variable with global scope.
perl:
Undeclared variables,which are permitted unless use strict is in effect,are global. If use strict is in effect,a global can be declared at the top level of a package (i.e. outside any blocks or functions) with the our keyword. A variable declared withmy inside a function will hide a global with the same name,if there is one.
PHP:
A variable is global if it is used at the top level (i.e. outside any function definition) or if it is declared inside a function with the global keyword. A function must use the global keyword to access the global variable.
python:
A variable is global if it is defined at the top level of a file (i.e. outside any function definition). Although the variable is global,it must be imported individually or be prefixed with the module name prefix to be accessed from another file. To be accessed from inside a function or method it must be declared with the global keyword.
ruby:
A variable is global if it starts with a dollar sign: $.
constant
How to declare a constant.
PHP:
A constant can be declared inside a class:
Refer to a class constant like this:
ruby:
Capitalized variables contain constants and class/module names. By convention,constants are all caps and class/module names are camel case. The ruby interpreter does not prevent modification of constants,it only gives a warning. Capitalized variables are globally visible,but a full or relative namespace name must be used to reach them: e.g. Math::PI.
assignment
How to assign a value to a variable.
perl:
Assignment operators have right precedence and evaluate to the right argument,so assignments can be chained:
python:
If the variable on the left has not prevIoUsly been defined in the current scope,then it is created. This may hide a variable in a containing scope.
Assignment does not return a value and cannot be used in an expression. Thus,assignment cannot be used in a conditional test,removing the possibility of using assignment (=) when an equality test (==) was intended. Assignments can nevertheless be chained to assign a value to multiple variables:
ruby:
Assignment operators have right precedence and evaluate to the right argument,so they can be chained. If the variable on the left does not exist,then it is created.
parallel assignment
How to assign values to variables in parallel.
python:
The r-value can be a list or tuple:
Nested sequences of expression can be assigned to a nested sequences of l-values,provided the nesting matches. This assignment will set a to 1,b to 2,and c to 3:
This assignment will raise a TypeError:
ruby:
The r-value can be an array:
swap
How to swap the values held by two variables.
compound assignment
Compound assignment operators mutate a variable,setting it to the value of an operation which takes the prevIoUs value of the variable as an argument.
If <OP> is a binary operator and the language has the compound assignment operator <OP>=,then the following are equivalent:
The compound assignment operators are displayed in this order:
First row: arithmetic operator assignment: addition,(float) division,integer division,modulus,and exponentiation.
Second row: string concatenation assignment and string replication assignment
Third row: logical operator assignment: and,or,xor
Fourth row: bit operator assignment: left shift,right shift,and,xor.
python:
Python compound assignment operators do not return a value and hence cannot be used in expressions.
increment and decrement
The C-style increment and decrement operators can be used to increment or decrement values. They return values and thus can be used in expressions. The prefix versions return the value in the variable after mutation,and the postfix version return the value before mutation.
Incrementing a value two or more times in an expression makes the order of evaluation significant:
Python avoids the problem by not having an in-expression increment or decrement.
Ruby mostly avoids the problem by providing a non-mutating increment and decrement. However,here is a Ruby expression which is dependent on order of evaluation:
perl:
The increment and decrement operators also work on strings. There are postfix versions of these operators which evaluate to the value before mutation:
PHP:
The increment and decrement operators also work on strings. There are postfix versions of these operators which evaluate to the value before mutation:
ruby:
The Integer class defines succ,96); padding-left:2px; padding-right:1px">pred,96); padding-left:2px; padding-right:1px">next,which is a synonym for succ.
The String class defines succ!,96); padding-left:2px; padding-right:1px">next!. succ! and next! mutate the string.
null
The null literal.
@L_683_502@
null test
How to test if a variable contains null.
perl:
$v == undef does not imply that $v is undef. Any comparison between undef and a falsehood will return true. The following comparisons are true:
PHP:
$v == NULL does not imply that $v is NULL,since any comparison between NULL and a falsehood will return true. In particular,the following comparisons are true:
undefined variable access
The result of attempting to access an undefined variable.
perl:
Perl does not distinguish between unset variables and variables that have been set to undef. In Perl,calling defined($a) does not result in a error if $a is undefined,even with the strict pragma.
PHP:
PHP does not provide the programmer with a mechanism to distinguish an undefined variable from a variable which has been set to NULL.
A test showing that isset is the logical negation of is_null.
python:
How to test if a variable is defined:
ruby:
How to test if a variable is defined:
conditional expression
How to write a conditional expression. A ternary operator is an operator which takes three arguments. Since
condition ? true value : false value
is the only ternary operator in C,it is unambiguous to refer to it as the ternary operator.
python:
The Python conditional expression comes from Algol.
ruby:
The Ruby if statement is also an expression:
Arithmetic and Logic
true and false
Literals for the booleans.
These are the return values of the relational operators.
PHP:
Any identifier which matches TRUE case-insensitive can be used for the TRUE boolean. Similarly for FALSE.
In general,PHP variable names are case-sensitive,but function names are case-insensitive.
When converted to a string for display purposes,TRUE renders as "1" and FALSE as "". The equality tests TRUE == 1and FALSE == "" evaluate as TRUE but the equality tests TRUE === 1 and FALSE === "" evaluate as FALSE.
falsehoods
Values which behave like the false boolean in a conditional context.
Examples of conditional contexts are the conditional clause of an if statement and the test of a while loop.
python:
Whether a object evaluates to True or False in a boolean context can be customized by implementing a __nonzero__(Python 2) or __bool__ (Python 3) instance method for the class.
logical operators
Logical and,and not.
PHP,perl,ruby:
&& and || have higher precedence than assignment,compound assignment,and the ternary operator (?:),which have higher precedence than and and or.
relational operators
Equality,inequality,greater than,less than,greater than or equal,less than or equal.
PHP:
Most of the relational operators will convert a string to a number if the other operand is a number. Thus 0 == "0" is true. The operators === and !== do not perform this conversion,so 0 === "0" is false.
perl:
The operators: == != > < >= <= convert strings to numbers before performing a comparison. Many string evaluate as zero in a numeric context and are equal according to the == operator. To perform a lexicographic string comparison,use: eq,ne, gt, lt, ge, le.
python:
Relational operators can be chained. The following expressions evaluate to true:
In general if Ai are expressions and opi are relational operators,then
A1 op1 A2 op2 A3 … An opn An+1
is true if and only if each of the following is true
2
3
…
n+1
compare strings
How to compare strings.
min and max
How to get the min and max.
three value comparison
Binary comparison operators which return -1,or 1 depending upon whether the left argument is less than,equal to,or greater than the right argument.
The <=> symbol is called the spaceship operator.
arithmetic operators
The operators for addition,and exponentiation.
integer division
How to get the integer quotient of two integers.
perl:
The integer pragma makes all arithmetic operations integer operations. Floating point numbers are truncated before they are used. Hence integer division could be performed with:
divmod
How to get the quotient and remainder with single function call.
integer division by zero
What happens when an integer is divided by zero.
float division
How to perform floating point division,even if the operands might be integers.
float division by zero
What happens when a float is divided by zero.
power
How to get the value of a number raised to a power.
sqrt
The square root function.
sqrt -1
The result of taking the square root of negative one.
transcendental functions
Some mathematical functions. Trigonometric functions are in radians unless otherwise noted. Logarithms are natural unless otherwise noted.
python:
Python also has math.log10. To compute the log of x for base b,use:
ruby:
Ruby also has Math.log2, Math.log10. To compute the log of x for base b,use
transcendental constants
Constants for π and Euler's constant.
float truncation
How to truncate a float to the nearest integer towards zero; how to round a float to the nearest integer; how to find the nearest integer above a float; how to find the nearest integer below a float; how to take the absolute value.
perl:
The CPAN module Number::Format provides a round function. The 2nd argument specifies the number of digits to keep to the right of the radix. The default is 2.
absolute value
How to get the absolute value of a number.
integer overflow
What happens when the largest representable integer is exceeded.
float overflow
What happens when the largest representable float is exceeded.
rational numbers
How to create rational numbers and get the numerator and denominator.
ruby:
Require the library mathn and integer division will yield rationals instead of truncated integers.
complex numbers
python:
Most of the functions in math have analogues in cmath which will work correctly on complex numbers.
random integer,normal float
How to generate a random integer between 0 and 99,include,float between zero and one in a uniform distribution,or a float in a normal distribution with mean zero and standard deviation one.
set random seed,get and restore seed
How to set the random seed; how to get the current random seed and later restore it.
All the languages in the sheet set the seed automatically to a value that is difficult to predict. The Ruby MRI interpreter uses the current time and process ID,for example. As a result there is usually no need to set the seed.
Setting the seed to a hardcoded value yields a random but repeatable sequence of numbers. This can be used to ensure that unit tests which cover code using random numbers doesn't intermittently fail.
The seed is global state. If multiple functions are generating random numbers then saving and restoring the seed may be necessary to produce a repeatable sequence.
bit operators
The bit operators for left shift,inclusive or,exclusive or,and negation.
Binary,and hex integer literals
radix
How to convert integers to strings of digits of a given base. How to convert such strings into integers.
perl
Perl has the functions oct and hex which convert strings encoded in octal and hex and return the corresponding integer. The oct function will handle binary or hex encoded strings if they have "0b" or "0x" prefixes.
oct("60")
oct("060")
oct("0b101010")
oct("0x2a")
hex("2a")
hex("0x2a")
python
Python has the functions bin,96); padding-left:2px; padding-right:1px">oct,96); padding-left:2px; padding-right:1px">hex which take an integer and return a string encoding the integer in base 2,8,and 16.
bin(42)
oct(42)
hex(42)
Strings
string type
The type or types using for strings.
perl:
Perl has supported multibyte characters since version 5.6.
PHP:
PHP assumes all strings have single byte characters.
python:
In Python 2.7 the str type assumes single byte characters. A separate unicode type is available for working with Unicode strings.
In Python 3 the str type supports multibtye characters and the unicode type has been removed.
There is a mutable bytearray type and an immutable bytes type for working with sequences of bytes.
ruby:
The {String}} type supports multibtye characters. All strings have an explicit Encoding.
string literal
The Syntax for string literals.
perl:
When use strict is not in effect bareword strings are permitted.
Barewords are strings without quote delimiters. They are a feature of shells. Barewords cannot contain whitespace or any other character used by the tokenizer to distinguish words.
Before Perl 5 subroutines were invoked with an ampersand prefix & or the older do keyword. With Perl 5 neither is required,but this made it impossible to distinguish a bareword string from a subroutine without knowing all the subroutines which are in scope.
The following code illustrates the bareword ambiguity:
no strict;
print rich . "\n"; # prints "rich"; rich is a bareword string
sub rich { return "poor" }
print rich . "\n"; # prints "poor"; rich is now a subroutine
newline in literal
Whether newlines are permitted in string literals.
python:
Newlines are not permitted in single quote and double quote string literals. A string can continue onto the following line if the last character on the line is a backslash. In this case,neither the backslash nor the newline are taken to be part of the string.
Triple quote literals,which are string literals terminated by three single quotes or three double quotes,can contain newlines:
'''This is
two lines'''
"""This is also
two lines"""
literal escapes
Backslash escape sequences for inserting special characters into string literals.
unrecognized backslash escape sequence | ||||
---|---|---|---|---|
double quote | single quote | |||
PHP | preserve backslash | preserve backslash | ||
Perl | drop backslash | Python | Ruby | preserve backslash |
perl:
In addition to the character escapes,Perl has the following translation escapes:
\u | make next character uppercase |
\l | make next character lowercase |
\U | make following characters uppercase |
\L | make following characters lowercase |
\Q | backslash escape following nonalphanumeric characters |
\E | end \U,\L,or \Q section |
When use charnames is in effect the \N escape sequence is available:
python:
When string literals have an r or R prefix there are no backslash escape sequences and any backslashes thus appear in the created string. The delimiter can be inserted into a string if it is preceded by a backslash,but the backslash is also inserted. It is thus not possible to create a string with an R prefix that ends in a backslash. The r and R prefixes can be used with single or double quotes:
The \uhhhh escapes are also available inside Python 2 Unicode literals. Unicode literals have a u prefiix:
This Syntax is also available in Python 3.3,but not Python 3.2. In Python 3.3 it creates a string of type str which has the same features as the unicode type of Python 2.7.
custom delimiters
How to specify custom delimiters for single and double quoted strings. These can be used to avoid backslash escaping. If the left delimiter is (,[,or { the right delimiter must be ),],or },respectively.
here document
Here documents are strings terminated by a custom identifier. They perform variable substitution and honor the same backslash escapes as double quoted strings.
perl:
Put the custom identifier in single quotes to prevent variable interpolation and backslash escape interpretation:
python:
Python lacks variable interpolation in strings. Triple quotes honor the same backslash escape sequences as regular quotes,so triple quotes can otherwise be used like here documents:
ruby:
Put the customer identifier in single quotes to prevent variable interpolation and backslash escape interpretation:
variable interpolation
How to interpolate variables into strings.
python:
str.format will take named or positional parameters. When used with named parameters str.format can mimic the variable interpolation feature of the other languages.
A selection of variables in scope can be passed explicitly:
Python 3 has format_map which accepts a dict as an argument:
expression interpolation
How to interpolate the result of evaluating an expression into a string.
format
How to create a string using a printf style format.
python:
The % operator will interpolate arguments into printf-style format strings.
The str.format with positional parameters provides an alternative format using curly braces {0},{1},… for replacement fields.
The curly braces are escaped by doubling:
If the replacement fields appear in sequential order and aren't repeated,the numbers can be omitted:
are strings mutable?
Are strings mutable?
copy string
How to copy a string such that changes to the original do not modify the copy.
concatenate
The string concatenation operator.
replicate
The string replication operator.
translate case
How to put a string into all caps or all lower case letters.
capitalize
How to capitalize a string and the words in a string.
ruby:
Rails monkey patches the String class with the titleize method for capitalizing the words in a string.
trim
How to remove whitespace from the ends of a string.
perl:
An example of how to trim a string without installing a library:
The return value of the =~ operator is boolean,indicating whether a match occurred. Also the left hand side of the =~operator must be a scalar variable that can be modified. Using the =~ operator is necessarily imperative,unlike theText::Trim functions which can be used in expressions.
pad
How to pad the edge of a string with spaces so that it is a prescribed length.
number to string
How to convert numeric data to string data.
@H_404_10777@string to numberHow to convert string data to numeric data.
PHP:
PHP converts a scalar to the desired type automatically and does not raise an error if the string contains non-numeric data. If the start of the string is not numeric,the string evaluates to zero in a numeric context.
perl:
Perl converts a scalar to the desired type automatically and does not raise an error if the string contains non-numeric data. If the start of the string is not numeric,the string evaluates to zero in a numeric context.
python:
float and int raise an error if called on a string and any part of the string is not numeric.
ruby:
to_i and to_f always succeed on a string,returning the numeric value of the digits at the start of the string,or zero if there are no initial digits.
join
How to concatenate the elements of an array into a string with a separator.
split
How to split a string containing a separator into an array of substrings.
See also scan.
python:
str.split() takes simple strings as delimiters; use re.split() to split on a regular expression:
split in two
How to split a string in two.
python:
Methods for splitting a string into three parts using the first or last occurrence of a substring:
split and keep delimiters
How to split a string with the delimiters preserved as separate elements.
length
How to get the length in characters of a string.
index of substring
How to find the index of the leftmost occurrence of a substring in a string; how to find the index of the rightmost occurrence.
extract substring
How to extract a substring from a string by index.
extract character
How to extract a character from a string by its index.
chr and ord
Converting characters to ASCII codes and back.
The languages in this reference sheet do not have character literals,so characters are represented by strings of length one.
to array of characters
How to split a string into an array of single character strings.
translate characters
How to apply a character mapping to a string.
delete characters
How to remove all specified characters from a string; how to remove all but the specified characters from a string.
squeeze characters
How to replace multiple adjacent occurrences of a character with a single occurrence.
Regular Expressions
- PHP PCRE Regexes
- perlre and perlreref
- Python re library: 2.7, 3.1
- Ruby Regexp
Regular expressions or regexes are a way of specifying sets of strings. If a string belongs to the set,the string and regex "match". Regexes can also be used to parse strings.
The modern notation for regexes was introduced by Unix command line tools in the 1970s. POSIX standardized the notation into two types: extended regexes and the more archaic basic regexes. Perl regexes are extended regexes augmented by new character class abbreviations and a few other features introduced by the Perl interpreter in the 1990s. All the languages in this sheet use Perl regexes.
Any string that doesn't contain regex Metacharacters is a regex which matches itself. The regex Metacharacters are: [ ] . | ( ) * + ? { } ^ $ \
character classes: [ ] .
A character class is a set of characters in brackets: [ ]. When used in a regex it matches any character it contains.
Character classes have their own set of Metacharacters: ^ - \ ]
The ^ is only special when it is the first character in the character class. Such a character class matches its complement; that is,any character not inside the brackets. When not the first character the ^ refers to itself.
The hyphen is used to specify character ranges: e.g. 0-9 or A-Z. When the hyphen is first or last inside the brackets it matches itself.
The backslash can be used to escape the above characters or the terminal character class delimiter: ]. It can be used in character class abbreviations or string backslash escapes.
The period . is a character class abbreviation which matches any character except for newline. In all languages the period can be made to match all characters. PHP and Perl use the m modifier. Python uses the re.M flag. Ruby uses the s modifier.
character class abbreviations:
name | character class | |
---|---|---|
\d | digit | [0-9] |
\D | nondigit | [^0-9] |
\h | PHP,Perl: horizontal whitespace character Ruby: hex digit |
Ruby: [0-9a-fA-F] |
\H | Ruby: not a hex digit | Ruby: [^0-9a-fA-F] |
\s | whitespace character | [ \t\r\n\f] |
\S | non whitespace character | [^ \t\r\n\f] |
\v | vertical whitespace character | [\r\n\f] |
\V | not a vertical whitespace character | [^\r\n\f] |
\w | word character | [A-Za-z0-9_] |
\W | non word character | [^A-Za-z0-9_] |
alternation and grouping: | ( )
The vertical pipe | is used for alternation and parens () for grouping.
A vertical pipe takes as its arguments everything up to the next vertical pipe,enclosing paren,or end of string.
Parentheses control the scope of alternation and the quantifiers described below. They are also used for capturing groups,which are the substrings which matched parenthesized parts of the regular expression. Each language numbers the groups and provides a mechanism for extracting them when a match is made. A parenthesized subexpression can be removed from the groups with this Syntax: (?:expr)
quantifiers: * + ? { }
As an argument quantifiers take the preceding regular character,character class,or group. The argument can itself be quantified,so that ^a{4}*$ matches strings with the letter a in multiples of 4.