I have been trying to teach myself MySQL, and was wondering if somebody could please explain the difference between the use of the regex metacharacters '*' and '?'. The book I am using describes them both as "matching (0) or one instances of the strings preceding it". I tried using both while looking for the same thing in a practice table I created and got exactly the same output, so if one of the operators is supposed to be greedy and the other not, it doesn't look like that is always the case with every table.
Edit 1: I'm including a screenshot of the output I got from '*' that shows it matching a statement of the form 'ax*' to just a.
Edit 2: regex101.com does not list MySQL as a "flavor" and when I try to do 'al*' to Alexandra there, it says no match for any of the flavors. Is the fact that MySQL Workbench is returning Alexandra as one of the outputs something specific to MySQL that does not apply to any of these other languages?
They are not quite the same. "*" means "0 or more". "?" means "0 or 1", like "optional". So, given "ax*b" and "ax?b":
Neither will match "a"
Both will match "ab"
Both will match "axb"
Only the first will match "axxb" or "axxxxxxb"
Related
I am using mySql Data base I have a table with a column for account hierarchy, the values in this column look like this
/home/first level hierarchy / second level hierarchy / third level hierarchy/
(some have only one level and some have 3 levels)
I want to get only the first level hierarchy items
my SQL query looks like this
SELECT Account.name FROM Account WHERE account_hierarchy like "/home/%/"
the problem is that i am getting in the result all the levels after home since they all ends with /
is there any way in SQL to get only the first level
I think you want exactly three slashes. You can get that using:
where hierarchy like '/home/%/' and
hierarchy not like '/home/%/%/'
In databases that support regular expressions, there are alternative solutions.
Actually, if you want just a beginning and ending slash, then there is no slash in the middle with other characters around it. So you can use:
where hierarchy not like '/home/%_/_%'
This assumes that all begin with '/home/'.
In MySQL, you can use REGEXP_SUBSTR
Example:
SELECT regexp_substr('/a/b/c','[a-z]+',3), returns b
Because 'b' is the piece after the second '/'.
You might need to change the regular expression '[a-z]+'. This on only matches lower-case paths. If you also need upper-case matches, change it to [a-zA-Z]+.
All the other posibilitues of regular expressions (in MySQL) are explained here.
I'm trying to search through a database of sofware titles for those that have an interior capital letter (e.g PowerPoiint, inCase).
I tried
select * from table where field REGEXP '^([a-z][A-Z]+)+$'
This seemed to work as it returned a subset of the table and most were correct but a fair amount were not (e.g Alias). Clearly it is doing something right but not sure what; could it be that the ascii is somehow messed up?
Try this as your RegEx pattern:
^[A-z]+[A-Z][A-z]+$
It will match all the examples above (PowerPoint, inCase), and not match 'Alias', one of the examples that you are having trouble with.
This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Simulating regex capture groups in mysql
Good day,
I have many rows of data stored in a MySQL table. A typical value could look something like this:
::image-gallery::
::gallery-entry::images/01.jpg::/gallery-entry::
::/image-gallery::
Is there a way - by means of a regular expression that I can a) extract the term image gallery from the first line (it could be any phrase, not just image-gallery) and then extract the center line as two separate values like this:
gallery-entry and then images/01.jpg
There could be many lines of ::gallery-entry:: values, and they could be called anything as well. A more complete example would be:
::image-gallery::
::title::MY GALLERY::/title::
::date::2011-05-20::/date::
::gallery-entry::images/01.jpg::/gallery-entry::
::/image-gallery::
In essence I want this information: The content type (image-gallery) in the above case, first line and last line. Then I need the title as a key value style pair, so title as the key and MY GALLERY as the value. Then, subsequently, I would need all the rows of fields thereafter (gallery-entry) as key value pairs too.
This is for a migration script where data from an old system will be migrated over to a new system with different syntax.
If MySQL select statements would not work, would it be easier to parse the results with a PHP script for data extraction?
Any and all help is always appreciated.
Kind regards,
Simon
Try this regex:
::image-gallery::\s+::title::(.*?)::/title::.*?::gallery-entry::(.*?)::/gallery-entry::\s+::/image-gallery::
Use single-line mode (/pattern/s) so the .*? chews up newlines.
Your key-value pairs will be:
title: $1 (matching group 1)
gallery-entry: $2 (matching group 2)
From simulating-regex-capture-groups-in-mysql there does not seem to be a way to easily capture groups with a regex in mysql. The reason is that MySQL does not natively support capture groups in a regex. If you want that functionality you can use a server side extension like lib_mysqludf_preg to add that capability to MySQL.
The easiest way is to extract the whole column with SQL and then do the text matching in another language (such as php).
In my tests kenbritton's regex didn't work, but building off of it the following regex worked on your test data:
::image-gallery::\s+::title::(.*?)::\/title::\s+(?:.*\s+)*::gallery-entry::(.*?)::\/gallery-entry::\s+::\/image-gallery::
This probably has something to do with my understanding of full text search or perhaps a known issue. My Java code creates search term for full text search on MySQL like this -
+word*
This works fine if the value in the DB column contains more text than the word itself. However, if the value is exact - no result are returned. I expected it to return results when value is an exact match. Let me give an example -
Assume that DB has column name with value "Manish", now if I search with this -
+Manis*
It does return the result correctly, but if I try this -
+Manish*
It doesn't return any result, though exact match exists in DB column - Name. How can I obtain the desired behaviour in both these cases? Removing + sign works, but it returns far too many results when there are two or more words.
Any help, pointers would be highly appreciated! I am using MySQL 5.0
TIA,
- Manish
Try removing the +
+Man searches for Man but not Manish
Man* searches for Man and Manish.
I have a database of phrases that users will search for from their own input. I want them to find the phrase regardless of what punctuation they use. For example if the phrase, "Hey, how are you?" is in the row, I want all of the following searches to return it:
"Hey! How are you?!"
"Hey how are you?"
"Hey :) How are you?"
Right now, I have the columns 'phrase' and 'phrase_search'. Phrase search is a stripped down version of phrase so our example would be 'hey-how-are-you'.
Is there anyway to achieve this without storing the phrase twice?
Thank you!
-Nicky
What you've done is probably the most time-efficient way of doing it. Yes, it requires double the space, but is that an issue?
If it is an issue, a possible solution would be to convert your search string to use wildcards (eg. %Hey%how%are%you%) and then filter the SQL results in your code by applying the same stripping function to the database input and the search string and comparing them. The rationale behind this is that there should be relatively few matches with non-punctuation characters in-between the words, so you're still getting MySQL to do the "heavy lifting" while your PHP/Perl/Python/whatever code can do a more fine-grained check on a relatively small number of rows.
(This assumes that you have some code calling this, rather than a user typing the SQL query from the command line, of course.)