Can seem to find a substring function in python.
Say I want to output the first 100 characters in a string, how can I do this?
I want to do it safely also, meaning if the string is 50 characters it shouldn't fail.
print my_string[0:100]
From python tutorial:
Degenerate slice indices are handled
gracefully: an index that is too large
is replaced by the string size, an
upper bound smaller than the lower
bound returns an empty string.
So it is safe to use x[:100].
Easy:
print mystring[:100]
To answer Philipp's concern ( in the comments ), slicing works ok for unicode strings too
>>> greek=u"αβγδεζηθικλμνξοπρςστυφχψω"
>>> print len(greek)
25
>>> print greek[:10]
αβγδεζηθικ
If you want to run the above code as a script, put this line at the top
# -*- coding: utf-8 -*-
If your editor doesn't save in utf-8, substitute the correct encoding
Slicing of arrays is done with [first:last+1].
One trick I tend to use a lot of is to indicate extra information with ellipses. So, if your field is one hundred characters, I would use:
if len(s) <= 100:
print s
else:
print "%s..."%(s[:97])
And yes, I know () is superfluous in this case for the % formatting operator, it's just my style.
String formatting using % is a great way to handle this. Here are some examples.
The formatting code '%s' converts '12345' to a string, but it's already a string.
>>> '%s' % '12345'
'12345'
'%.3s' specifies to use only the first three characters.
>>> '%.3s' % '12345'
'123'
'%.7s' says to use the first seven characters, but there are only five. No problem.
>>> '%.7s' % '12345'
'12345'
'%7s' uses up to seven characters, filling missing characters with spaces on the left.
>>> '%7s' % '12345'
' 12345'
'%-7s' is the same thing, except filling missing characters on the right.
>>> '%-7s' % '12345'
'12345 '
'%5.3' says use the first three characters, but fill it with spaces on the left to total five characters.
>>> '%5.3s' % '12345'
' 123'
Same thing except filling on the right.
>>> '%-5.3s' % '12345'
'123 '
Can handle multiple arguments too!
>>> 'do u no %-4.3sda%3.2s wae' % ('12345', 6789)
'do u no 123 da 67 wae'
If you require even more flexibility, str.format() is available too. Here is documentation for both.
Most of previous examples will raise an exception in case your string is not long enough.
Another approach is to use
'yourstring'.ljust(100)[:100].strip().
This will give you first 100 chars.
You might get a shorter string in case your string last chars are spaces.
[start:stop:step]
So If you want to take only 100 first character, use your_string[0:100] or your_string[:100]
If you want to take only the character at even position, use your_string[::2]
The "default values" for start is 0, for stop - len of string, and for step - 1. So when you don't provide one of its and put ':', it'll use it default value.
Related
This question already has answers here:
Understanding slicing
(38 answers)
Closed 29 days ago.
I want to get a new string from the third character to the end of the string, e.g. myString[2:end]. If omitting the second part means 'to the end', and if you omit the first part, does it start from the start?
>>> x = "Hello World!"
>>> x[2:]
'llo World!'
>>> x[:2]
'He'
>>> x[:-2]
'Hello Worl'
>>> x[-2:]
'd!'
>>> x[2:-2]
'llo Worl'
Python calls this concept "slicing" and it works on more than just strings. Take a look here for a comprehensive introduction.
Just for completeness as nobody else has mentioned it. The third parameter to an array slice is a step. So reversing a string is as simple as:
some_string[::-1]
Or selecting alternate characters would be:
"H-e-l-l-o- -W-o-r-l-d"[::2] # outputs "Hello World"
The ability to step forwards and backwards through the string maintains consistency with being able to array slice from the start or end.
Substr() normally (i.e. PHP and Perl) works this way:
s = Substr(s, beginning, LENGTH)
So the parameters are beginning and LENGTH.
But Python's behaviour is different; it expects beginning and one after END (!). This is difficult to spot by beginners. So the correct replacement for Substr(s, beginning, LENGTH) is
s = s[ beginning : beginning + LENGTH]
A common way to achieve this is by string slicing.
MyString[a:b] gives you a substring from index a to (b - 1).
One example seems to be missing here: full (shallow) copy.
>>> x = "Hello World!"
>>> x
'Hello World!'
>>> x[:]
'Hello World!'
>>> x==x[:]
True
>>>
This is a common idiom for creating a copy of sequence types (not of interned strings), [:]. Shallow copies a list, see Python list slice syntax used for no obvious reason.
Is there a way to substring a string in Python, to get a new string from the 3rd character to the end of the string?
Maybe like myString[2:end]?
Yes, this actually works if you assign, or bind, the name,end, to constant singleton, None:
>>> end = None
>>> myString = '1234567890'
>>> myString[2:end]
'34567890'
Slice notation has 3 important arguments:
start
stop
step
Their defaults when not given are None - but we can pass them explicitly:
>>> stop = step = None
>>> start = 2
>>> myString[start:stop:step]
'34567890'
If leaving the second part means 'till the end', if you leave the first part, does it start from the start?
Yes, for example:
>>> start = None
>>> stop = 2
>>> myString[start:stop:step]
'12'
Note that we include start in the slice, but we only go up to, and not including, stop.
When step is None, by default the slice uses 1 for the step. If you step with a negative integer, Python is smart enough to go from the end to the beginning.
>>> myString[::-1]
'0987654321'
I explain slice notation in great detail in my answer to Explain slice notation Question.
I would like to add two points to the discussion:
You can use None instead on an empty space to specify "from the start" or "to the end":
'abcde'[2:None] == 'abcde'[2:] == 'cde'
This is particularly helpful in functions, where you can't provide an empty space as an argument:
def substring(s, start, end):
"""Remove `start` characters from the beginning and `end`
characters from the end of string `s`.
Examples
--------
>>> substring('abcde', 0, 3)
'abc'
>>> substring('abcde', 1, None)
'bcde'
"""
return s[start:end]
Python has slice objects:
idx = slice(2, None)
'abcde'[idx] == 'abcde'[2:] == 'cde'
You've got it right there except for "end". It's called slice notation. Your example should read:
new_sub_string = myString[2:]
If you leave out the second parameter it is implicitly the end of the string.
text = "StackOverflow"
#using python slicing, you can get different subsets of the above string
#reverse of the string
text[::-1] # 'wolfrevOkcatS'
#fist five characters
text[:5] # Stack'
#last five characters
text[-5:] # 'rflow'
#3rd character to the fifth character
text[2:5] # 'rflow'
#characters at even positions
text[1::2] # 'tcOefo'
If myString contains an account number that begins at offset 6 and has length 9, then you can extract the account number this way: acct = myString[6:][:9].
If the OP accepts that, they might want to try, in an experimental fashion,
myString[2:][:999999]
It works - no error is raised, and no default 'string padding' occurs.
Well, I got a situation where I needed to translate a PHP script to Python, and it had many usages of substr(string, beginning, LENGTH).
If I chose Python's string[beginning:end] I'd have to calculate a lot of end indexes, so the easier way was to use string[beginning:][:length], it saved me a lot of trouble.
str1='There you are'
>>> str1[:]
'There you are'
>>> str1[1:]
'here you are'
#To print alternate characters skipping one element in between
>>> str1[::2]
'Teeyuae'
#To print last element of last two elements
>>> str1[:-2:-1]
'e'
#Similarly
>>> str1[:-2:-1]
'e'
#Using slice datatype
>>> str1='There you are'
>>> s1=slice(2,6)
>>> str1[s1]
'ere '
Maybe I missed it, but I couldn't find a complete answer on this page to the original question(s) because variables are not further discussed here. So I had to go on searching.
Since I'm not yet allowed to comment, let me add my conclusion here. I'm sure I was not the only one interested in it when accessing this page:
>>>myString = 'Hello World'
>>>end = 5
>>>myString[2:end]
'llo'
If you leave the first part, you get
>>>myString[:end]
'Hello'
And if you left the : in the middle as well you got the simplest substring, which would be the 5th character (count starting with 0, so it's the blank in this case):
>>>myString[end]
' '
Using hardcoded indexes itself can be a mess.
In order to avoid that, Python offers a built-in object slice().
string = "my company has 1000$ on profit, but I lost 500$ gambling."
If we want to know how many money I got left.
Normal solution:
final = int(string[15:19]) - int(string[43:46])
print(final)
>>>500
Using slices:
EARNINGS = slice(15, 19)
LOSSES = slice(43, 46)
final = int(string[EARNINGS]) - int(string[LOSSES])
print(final)
>>>500
Using slice you gain readability.
a="Helloo"
print(a[:-1])
In the above code, [:-1] declares to print from the starting till the maximum limit-1.
OUTPUT :
>>> Hello
Note: Here a [:-1] is also the same as a [0:-1] and a [0:len(a)-1]
a="I Am Siva"
print(a[2:])
OUTPUT:
>>> Am Siva
In the above code a [2:] declares to print a from index 2 till the last element.
Remember that if you set the maximum limit to print a string, as (x) then it will print the string till (x-1) and also remember that the index of a list or string will always start from 0.
I have a simpler solution using for loop to find a given substring in a string.
Let's say we have two string variables,
main_string = "lullaby"
match_string = "ll"
If you want to check whether the given match string exists in the main string, you can do this,
match_string_len = len(match_string)
for index,value in enumerate(main_string):
sub_string = main_string[index:match_string_len+index]
if sub_string == match_string:
print("match string found in main string")
I can enter an octal value of 'up to 3 characters' in a string.
Is there any way to enter an octal value of only 1 character?
For instance.
If I want to print \0 followed by "Hello", I can do:
"\0Hello"
but if I want to print \0 followed by "12345" I can't do
"\012345"
instead I have to do
"\00012345"
This can, in very obscure scenarios, lead to inconsistent behaviour.
def parseAsString(characters):
output = ['H','I''!','\\','0'] + characters
print("".join(output).encode().decode('unicode_escape'));
parseAsString(['Y','O','U'])
#Output:
#>HI! YOU
parseAsString(['1','2','3'])
#Output:
#>HI!
#>3
The answer to this is, when you're dealing with \0, to either.
Always remember to explicitly use \000 or \x00, this may not be possible if your raw text is coming from another source.
When dealing with raw strings AND concatenating them, always decode each constituent part first, then concatenate them last, not the other way around.
For instance the parser will do this for you if you concatenate strings together:
"\0" + "Hello"
and
"\0" + "12345"
Both work consistently as expected., because "\0" is converted to "\x00" before being concatenated with the rest of the string.
Or, in the more obscure scenario:
def safeParseAsString(characters):
output = "".join(['H','I''!','\\','0']).encode().decode('unicode_escape')
output +="".join(characters).encode().decode('unicode_escape')
print(output)
safeParseAsString(['Y','O','U'])
#Output:
#>HI! YOU
safeParseAsString(['1','2','3'])
#Output:
#>HI! 123
I would like to find the most efficient and simple way to test in python if a string passes the following criteria:
contains nothing except:
digits (the numbers 0-9)
decimal points: '.'
the letter 'e'
the sign '+' or '-'
spaces (any number of them)
tabs (any number of them)
I can do this easily with nested 'if' loops, etc., but i'm wondering if there's a more convenient way...
For example, I would want the string:
0.0009017041601 5.13623e-05 0.00137531 0.00124203
to be 'true' and all the following to be 'false':
# File generated at 10:45am Tuesday, July 8th
# Velocity: 82.568
# Ambient Pressure: 150000.0
Time(seconds) Force_x Force_y Force_z
That's trivial for a regex, using a character class:
import re
if re.match(r"[0-9e \t+.-]*$", subject):
# Match!
However, that will (according to the rules) also match eeeee or +-e-+ etc...
If what you actually want to do is check whether a given string is a valid number, you could simply use
try:
num = float(subject)
except ValueError:
print("Illegal value")
This will handle strings like "+34" or "-4e-50" or " 3.456e7 ".
import re
if re.match(r"^[0-9\te+ -]+$",x):
print "yes"
else:
print "no"
You can try this.If there is a match,its a pass else fail.Here x will be your string.
Easiest way to check whether the string has only required characters is by using the string.translate method.
num = "1234e+5"
if num.translate(None, "0123456789e+- \t"
print "pass"
else:
print "Wrong character present!!!"
You can add any character at the second parameter in the translate method other than that I mentioned.
You dont need to use regular expressions just use a test_list and all operation :
>>> from string import digits
>>> test_list=list(digits)+['+','-',' ','\t','e','.']
>>> all(i in test_list for i in s)
Demo:
>>> s ='+4534e '
>>> all(i in test_list for i in s)
True
>>> s='+9328a '
>>> all(i in test_list for i in s)
False
>>> s="0.0009017041601 5.13623e-05 0.00137531 0.00124203"
>>> all(i in test_list for i in s)
True
Performance wise, running a regular expression check is costly, depending on the expression. Also running a regex check for each valid line (i.e. lines which the value should be "True") will be costly, especially because you'll end up parsing each line with a regex and parse the same line again to get the numbers.
You did not say what you wanted to do with the data so I will empirically assume a few things.
First off in a case like this I would make sure the data source is always formatted the same way. Using your example as a template I would then define the following convention:
any line, which first non-blank character is a hash sign is ignored
any blank line is ignored
any line that contains only spaces is ignored
This kind of convention makes parsing much easier since you only need one regular expression to fit rules 1. to 3. : ^\s*(#|$), i.e. any number of space followed by either a hash sign or an end of line. On the performance side, this expression scans an entire line only when it's comprised of spaces and just spaces, which shall not happen very often. In other cases the expression scans a line and stops at the first non-space character, which means comments will be detected quickly for the scanning will stop as soon as the hash is encountered, at position 0 most of the time.
If you can also enforce the following convention:
the first non blank line of the remaining lines is the header with column names
there is no blank lines between samples
there are no comments in samples
Your code would then do the following:
read lines into line for as long as re.match(r'^\s*(#|$)', line) evaluates to True;
continue, reading headers from the next line into line: headers = line.split() and you have headers in a list.
You can use a namedtuple for your line layout — which I assume is constant throughout the same data table:
class WindSample(namedtuple('WindSample', 'time, force_x, force_y, force_z')):
def __new__(cls, time, force_x, force_y, force_z):
return super(WindSample, cls).__new__(
cls,
float(time),
float(force_x),
float(force_y),
float(force_z)
)
Parsing valid lines would then consist of the following, for each line:
try:
data = WindSample(*line.split())
except ValueError, e:
print e
Variable data would hold something such as:
>>> print data
WindSample(time=0.0009017041601, force_x=5.13623e-05, force_y=0.00137531, force_z=0.00124203)
The advantage is twofold:
you run costly regular expressions only for the smallest set of lines (i.e. blank lines and comments);
your code parses floats, raising an exception whenever parsing would yield something invalid.
I pulled out some tweets for analysis. When I separate the words in tweets I can see a lot of following expressions in my output:
\xe3\x81\x86\xe3\x81\xa1
I want to use regular expressions to replace these patterns with nothing. I am not very good with regex. I tried using solution in some similar questions but nothing worked for me. They are replacing characters like "xt" from "extra".
I am looking for something that will replace \x?? with nothing, considering ?? can be either a-f or 0-9 but word must be 4 letter and starting with \x.
Also i would like to add replacement for anything other than alphabets. Like:
"Hi!! my number is (7097868709809)."
after replacement should yield
"Hi my number is."
Input:
\xe3\x81\x86\xe3Extra
Output required:
Extra
What you are seeing is Unicode characters that can't directly be printed, expressed as pairs of hexadecimal digits. So for a more printable example:
>>> ord('a')
97
>>> hex(97)
'0x61'
>>> "\x61"
'a'
Note that what appears to be a sequence of four characters '\x61' evaluates to a single character, 'a'. Therefore:
?? can't "be anything" - they can be '0'-'9' or 'a'-'f'; and
Although e.g. r'\\x[0-9a-f]{2}' would match the sequence you see, that's not what the regex would parse - each "word" is really a single character.
You can remove the characters "other than alphabets" using e.g. string.printable:
>>> s = "foo\xe3\x81"
>>> s
'foo\xe3\x81'
>>> import string
>>> valid_chars = set(string.printable)
>>> "".join([c for c in s if c in valid_chars])
'foo'
Note that e.g. '\xe3' can be directly printed in Python 3 (it's 'ã'), but isn't included in string.printable. For more on Unicode in Python, see the docs.
I am trying to convert big integer number to hexadecimal, but in result I get extra "0x" in the beginning and "L" at the and. Is there any way to remove them. Thanks.
The number is:
44199528911754184119951207843369973680110397865530452125410391627149413347233422
34022212251821456884124472887618492329254364432818044014624401131830518339656484
40715571509533543461663355144401169142245599341189968078513301836094272490476436
03241723155291875985122856369808620004482511813588136695132933174030714932470268
09981252011612514384959816764532268676171324293234703159707742021429539550603471
00313840833815860718888322205486842202237569406420900108504810
In hex I get:
0x2ef1c78d2b66b31edec83f695809d2f86e5d135fb08f91b865675684e27e16c2faba5fcea548f3
b1f3a4139942584d90f8b2a64f48e698c1321eee4b431d81ae049e11a5aa85ff85adc2c891db9126
1f7f2c1a4d12403688002266798ddd053c2e2670ef2e3a506e41acd8cd346a79c091183febdda3ca
a852ce9ee2e126ca8ac66d3b196567ebd58d615955ed7c17fec5cca53ce1b1d84a323dc03e4fea63
461089e91b29e3834a60020437db8a76ea85ec75b4c07b3829597cfed185a70eeaL
The 0x is literal representation of hex numbers. And L at the end means it is a Long integer.
If you just want a hex representation of the number as a string without 0x and L, you can use string formatting with %x.
>>> a = 44199528911754184119951207843369973680110397
>>> hex(a)
'0x1fb62bdc9e54b041e61857943271b44aafb3dL'
>>> b = '%x' % a
>>> b
'1fb62bdc9e54b041e61857943271b44aafb3d'
Sure, go ahead and remove them.
hex(bignum).rstrip("L").lstrip("0x") or "0"
(Went the strip() route so it'll still work if those extra characters happen to not be there.)
Similar to Praveen's answer, you can also directly use built-in format().
>>> a = 44199528911754184119951207843369973680110397
>>> format(a, 'x')
'1fb62bdc9e54b041e61857943271b44aafb3d'
I think it's dangerous idea to use strip.
because lstrip or rstrip strips 0.
ex)
a = '0x0'
a.lstrip('0x')
''
result is '', not '0'.
In your case, you can simply use replace to prevent above situation.
Here's sample code.
hex(bignum).replace("L","").replace("0x","")
Be careful when using the accepted answer as lstrip('0x') will also remove any leading zeros, which may not be what you want, see below:
>>> account = '0x000067'
>>> account.lstrip('0x')
'67'
>>>
If you are sure that the '0x' prefix will always be there, it can be removed simply as follows:
>>> hex(42)
'0x2a'
>>> hex(42)[2:]
'2a'
>>>
[2:] will get every character in the string except for the first two.
A more elegant way would be
hex(_number)[2:-1]
but you have to be careful if you're working with gmpy mpz types,
then the 'L' doesn't exist at the end and you can just use
hex(mpz(_number))[2:]