One option is just to use the regex | character to try to match each of the substrings in the words in your Series s (still using str.contains).
You can construct the regex by joining the words in searchfor with |:
>>> searchfor = ['og', 'at']
>>> s[s.str.contains('|'.join(searchfor))]
0 cat
1 hat
2 dog
3 fog
dtype: object
As @AndyHayden noted in the comments below, take care if your substrings have special characters such as $ and ^ which you want to match literally. These characters have specific meanings in the context of regular expressions and will affect the matching.
You can make your list of substrings safer by escaping non-alphanumeric characters with re.escape:
>>> import re
>>> matches = ['$money', 'x^y']
>>> safe_matches = [re.escape(m) for m in matches]
>>> safe_matches
['\\$money', 'x\\^y']
The strings with in this new list will match each character literally when used with str.contains.
python - How to test if a string contains one of the substrings in a list, in pandas? - Stack Overflow
python - Pandas str.contains - Search for multiple values in a string and print the values in a new column - Stack Overflow
Find column names that contain multiple strings at the same time
php - Check if a string contain multiple specific words - Stack Overflow
One option is just to use the regex | character to try to match each of the substrings in the words in your Series s (still using str.contains).
You can construct the regex by joining the words in searchfor with |:
>>> searchfor = ['og', 'at']
>>> s[s.str.contains('|'.join(searchfor))]
0 cat
1 hat
2 dog
3 fog
dtype: object
As @AndyHayden noted in the comments below, take care if your substrings have special characters such as $ and ^ which you want to match literally. These characters have specific meanings in the context of regular expressions and will affect the matching.
You can make your list of substrings safer by escaping non-alphanumeric characters with re.escape:
>>> import re
>>> matches = ['$money', 'x^y']
>>> safe_matches = [re.escape(m) for m in matches]
>>> safe_matches
['\\$money', 'x\\^y']
The strings with in this new list will match each character literally when used with str.contains.
You can use str.contains alone with a regex pattern using OR (|):
s[s.str.contains('og|at')]
Or you could add the series to a dataframe then use str.contains:
df = pd.DataFrame(s)
df[s.str.contains('og|at')]
Output:
0 cat
1 hat
2 dog
3 fog
You need to set the regex flag (to interpret your search as a regular expression):
whatIwant = df['Column_with_text'].str.contains('value1|value2|value3',
case=False, regex=True)
df['New_Column'] = np.where(whatIwant, df['Column_with_text'])
------ Edit ------
Based on the updated problem statement, here is an updated answer:
You need to define a capture group in the regular expression using parentheses and use the extract() function to return the values found within the capture group. The lower() function deals with any upper case letters
df['MatchedValues'] = df['Text'].str.lower().str.extract( '('+pattern+')', expand=False)
Here is one way:
foods =['apples', 'oranges', 'grapes', 'blueberries']
def matcher(x):
for i in foods:
if i.lower() in x.lower():
return i
else:
return np.nan
df['Match'] = df['Text'].apply(matcher)
# Text Match
# 0 I want to buy some apples. apples
# 1 Oranges are good for the health. oranges
# 2 John is eating some grapes. grapes
# 3 This line does not contain any fruit names. NaN
# 4 I bought 2 blueberries yesterday. blueberries
I want to retrieve columns containing multiple strings in a dataframe
I coded like below to find columns containing 2 or more strings(strings to find: 'creating', 'damage') :
df[(df["account"].str.contains("creating|damage"))]
However, all lines containing 'damage' and all lines containing 'creating' were hit(union columns)
How can I retrieve columns that contain both 'damage' and 'creating' at the same time?( intersection columns)
For this, you will need Regular Expressions and the preg_match function.
Something like:
if(preg_match('(bad|naughty)', $data) === 1) { }
The reason your attempt didn't work
Regular Expressions are parsed by the PHP regex engine. The problem with your syntax is that you used the || operator. This is not a regex operator, so it is counted as part of the string.
As correctly stated above, if it's counted as part of the string you're looking to match: 'bad || naughty' as a string, rather than an expression!
You can't do something like this:
if (strpos($data, 'bad || naughty') !== false) {
instead, you can use regex:
if(preg_match("/(bad|naughty|other)/i", $data)){
//one of these string found
}
df=df[df.hash_tags.str.contains('cov|corona',na=False)]
na=False means nan values if present will be evaluated to false
Here is how the OR operator works with dataframe masking in Pandas:
df = df[
(df['hash_tags'].str.contains('cov')) |
(df['hash_tags'].str.contains('corona'))
]
I'd create a regular expression from the words:
Pattern pattern = Pattern.compile("(?=.*adsf)(?=.*qwer)");
if (pattern.matcher(input).find()) {
execute();
}
For more details, see this answer: https://stackoverflow.com/a/470602/660143
Editors note: Despite being heavily upvoted and accepted, this does not function the same as the code in the question.
executeis called on the first match, like a logical OR.
You could use an array:
String[] matches = new String[] {"adsf", "qwer"};
bool found = false;
for (String s : matches)
{
if (input.contains(s))
{
execute();
break;
}
}
This is efficient as the one posted by you but more maintainable. Looking for a more efficient solution sounds like a micro optimization that should be ignored until proven to be effectively a bottleneck of your code, in any case with a huge string set the solution could be a trie.
I have a vector of strings. Each string is an address that ends in a country name. I want to check if these addresses are in particular countries.
addresses = c("Hoofdstraat 1, Utrecht, Netherlands", "1 Main Drive, City, Maine, United States", "Äddress 1, Töwn, Sweden")
europeanCountries = c("Netherlands, "Sweden", "Ukraine")How do I get a vector of TRUE/FALSE statements saying if an address is or isn't in Europe?
Desired output:
TRUE FALSE TRUE
I want to do this without a for-loop, if possible.
Things I tried:
addresses %in% europeanCountries #Exact matches only. sjmisc::str_contains(europeanCountries, addresses) #Doesn't work with two factors.
To extend your current code you could use an array of target words to search for, and use a loop:
$a = 'How are you ?';
$targets = array('How', 'are');
foreach($targets as $t)
{
if (strpos($a,$t) !== false) {
echo 'one of the targets was found';
break;
}
}
Keep in mind that the use of strpos() in this way means that partial word matches can be found. For example if the target was ample in the string here is an example then a match will be found even though by definition the word ample isn't present.
For a whole word match, there is an example in the preg_match() documentation that can be expanded by adding a loop for multiple targets:
foreach($targets as $t)
{
if (preg_match("/\b" . $t . "\b/i", $a)) {
echo "A match was found.";
} else {
echo "A match was not found.";
}
}
Read it somewhere:
if(preg_match('[word1|word2]', $a)) { }