I use a php library to execute commands on a srcds-server via rcon. In this case I want to get all bans and their durations. When I execute listid via rcon, I get, after some parsing, for example this text:
1 STEAM_1:0:12345678 : permanent 2 STEAM_1:0:87654321 : 30.000 min
Now I want to get an array which contains the SteamID and the duration per set, like this:
$Bans = [
"STEAM_1:0:12345678" => "permanent",
"STEAM_1:0:87654321" => "30.000 min",
]
Since I can't use explode in a good way to do this for me (or at least I don't know how I should do that), I want to try it with regex. My attempt so far:
/^(?:\d\s)(STEAM_[0-5]:[01]:[0-9]{1,8})(?:\s:\s)(permanent|\d{1,}\.000\smin)/g
But that doesn't match it in the right way. How would you do it?
The right regex with preg_match_all is:
preg_match_all("/(?:\d\s)(STEAM_[0-5]:[01]:[0-9]{1,8})(?:\s:\s)(permanent|\d{1,}\.000\smin)/", $input_lines, $output_array);
I needed to remove the ^. Now, I don't even have to do all the exploding beforehand. I matches the right parts even from the raw result:
ID filter list: 2 entries 1 STEAM_1:0:12345678 : permanent 2 STEAM_1:0:87654321 : 30.000 min L 05/20/2015 - 15:48:53: rcon from "188.40.142.20:60799": command "listid"
Related
I am running the following SQL statement from a PHP script:
SELECT PHONE, COALESCE(PREFERREDNAME, POPULARNAME) FROM distilled_contacts WHERE PHONE LIKE :phone LIMIT 6
As obvious, the statement returns the first 6 matches against the table in question. The value I'm binding to the :phone variable is goes something like this:
$search = '%'.$search.'%';
Where, $search could be any string of numerals. The wildcard characters ensure that a search on, say 918, would return every record where the PHONE field contains 918:
9180078961
9879189872
0098976918
918
...
My problem is what happens if there does exist an entry with the value that matches the search string exactly, in this case 918 (the 4th item in the list above). Since there's a LIMIT 6, only the first 6 entries would be retrieved which may or may not contain the one with the exact match. Is there a way to ensure the results always contain the record with the exact match, on top of the resulting list, should one be available?
You could use an order by to ensure the exact match is always on top:
ORDER BY CASE WHEN PHONE = :phone THEN 1 ELSE 2 END
Using $search = ''.$search.'%' will show result, that matches the starting value.
I have a phone record tables as
phones(id, number);
It may have values as:-
1, 9801234567
2, 980 1234568
3, 9779801234569
4, 9801234570
5, 977 980 1234 571
If someone search for 980 1234567 (with spaces), I can remove the spaces before running the queries to get the result.
But my problem is when someone search for 9779801234571 with a condition that there is no regular format of number, it must return the last record i.e. 977 980 1234 571. Any idea how to do it efficiently?
Here is a way to do this:
where replace(phonenumber, ' ', '') = replace($phonenumber, ' ', '')
Doing this efficiently is another matter. For that, you would have to format your phone numbers in the database in a canonical format -- say by removing all the spaces in an update statement. Then put the number you are searching for in the same format. The query can then use an index on the column.
It is probably best to clean the phone numbers from whitespace before you write them into the database. You can easily to this using this function:
$string = preg_replace('/\s+/', '', $string);
Maybe you also have to strip out other characters like - or /.
Then you can use a simple WHERE condition without bells and whistles. This will also significantly improve the performance of your SELECT statement since you don't have to do conversions of your data in order to find the right row.
This is assuming that you fill the database yourself of course. If that's not the case, ignore this advise.
I have two different tables trackingevent and link
Trackingevent looks like
eventName|eventStamp
SHARE_FACEBOOK|2011-01-20 14:05:40
SHARE_TWEET|2011-01-20 14:47:57
SHARE_FLICKR|2011-01-20 15:08:58
SHARE_STATION_LOGIN|2011-01-20 15:09:09
EMAIL_SHARE|2011-01-20 15:10:13
CONTEST_ENTRY:BLAH DATA|2011-01-20 15:10:13
CONTEST_ENTRY:BLAH DATA|2011-01-20 15:10:13
and link looks like
id|emailSub
6|1
7|0
8|1
9|0
And what I need to do is I need to count all the SHARE_FACEBOOK
and all the SHARE_TWEET
and all the SHARE_FLICKR
and all the SHARE_STATION_LOGIN
and all the COPNTEST_ENTRIES (Without the rest of the data after the :)
AND EMAIL_SHARE
and somehow combine those with the amount of emailSub (equals to 1)
and amount of id.
So I get a returned array sort of like
EMAIL_SHARE 77
SHARE_FLICKR 9
SHARE_FACEBOOK 105
SHARE_STATION_LOGIN 223
SHARE_TWEET 18
# of ID's
# of emailsub=1
CONTEST_ENTERIES 550
I can get the first part of it using
SELECT eventName, COUNT(*) FROM trackingevent GROUP BY eventName
But I am confused with how to get the # of ID's in the link the # of emailsubs=1 and the number of CONTEST_ENTRY:BLAH DATA (the blah data changes).
Would I have to do three different sql queries and combine the data? Or could I somehow combine them into a single one or?
This should give you the count of each type using the prefix
SELECT LEFT(eventName,INSTR(CONCAT(eventName,':'),':')) as prefix, count(*)
FROM trackingevent
GROUP BY LEFT(eventName,INSTR(CONCAT(eventName,':'),':'))
You'll have to answer the questions in the comments if this isn't what you were asking for
i have an array, it have same data:
data range
115X0101-115X0200
115X0101-115X0200
115X0101-115X0200
the 115x mean production code..this unimportant.
we just concern at four digits behind it that we can counting.
1. i want script read or search "0101" and "0200" from 115X0101-115X0200
2. i have tried using regex to count them become 200-101=100
3. the "115X0101-115X0200" repeated until there are 20 data like this
4. after it reached 20, show result at page:
data range
100
If this is the raw data, the easiest way to extract it is probably using a regular expression, as you've mentioned.
You'll probably want something like this (in PHP):
# Get this from the database
$sql_results = array(
'115X0101-115X0200',
'115X0101-115X0200',
'115X0101-115X0200',
);
foreach($sql_results as $row)
{
preg_match_all('/\d{4}/', $row, $matches);
#200 #101
echo intval($matches[0][1]) - intval($matches[0][0]) + 1;
}
For each row, preg_match will find groups of 4 digits (\d{4}) and place them in $matches (use var_dump($matches) to see what it looks like).
More on Regex
Regular Expressions Cheatsheet
Regular Expressions Help
SQL Limit
Side note: If you only want 20 results at a time, you'll want to SELECT * FROM table LIMIT 20 when you query the database. To get rows 31-50 you'd use LIMIT 30, 20, which means offset by 30, then get 20 rows.
So, I have the following rows in the DB:
1 | /users/
2 | /users/admin/
3 | /users/admin/*
4 | /users/admin/mike/
5 | /users/admin/steve/docs/
The input URL is /users/admin/steve/, and the goal is to find the URL match from the DB.
I want to return #3 as the correct row, since the wildcard "*" specifies that anything can go in place of the asterisk. What would be the most efficient method for doing this?
Here's my initial thoughts, but I'm sure they could be improved upon:
Make a query to see if there's an exact URL match
If no matches, then retrieve all rows with "*" as the last character, in reverse order (so the more specific URLs take precedence)
For each row, if it (minus the "*") matches the input URL, then return it
If nothing is found, then we're SOL
Here's how I'd do it:
SELECT * FROM mytable AS m
WHERE <input-url> = m.urlpattern
OR <input-url> REGEXP REPLACE(m.urlpattern, '*', '.*');
The REPLACE() is to change the globbing-style wildcard into an equivalent regular-expression wildcard.
If I understand this correctly, something like this should work:
SELECT COALESCE(
(SELECT whatever FROM your query to see if there is an exact url),
(SELECT next approximation),
'SOL'
)