Ich wollte die preg_xxx
und regulären Ausdrücke zusammenfassen, die relativ verwendet werden, wenn ich mit PHP als Memorandum entwickle, also habe ich sie hier geschrieben.
Am Ende werden alle geändert und nach Bedarf verwendet, aber sie werden als vernünftige Basis verwendet.
Außerdem wird beschrieben, ob mit Python3 ähnliche Ergebnisse erzielt werden können.
Dies muss noch geprüft werden, aber als Beispiel für einen regulären Ausdruck. Sie wird je nach Eingabefall und Verwendung jedes Mal geändert.
/\A(\d{4})*[-\/]*(\d{1,2})[-\/]*(\d{1,2}) *((\d{1,2}):(\d{1,2})(:(\d{1,2}))*)*\Z/
Notation | Bedeutung |
---|---|
/ | Trennzeichen |
\A | Der Anfang der Zeichenfolge |
() | Als Set behandeln |
\d{4} | 4-stellige Nummer |
* | Wiederholen Sie 0 oder mehr Mal des vorherigen Musters |
[] | Zeichensatz,[]Einer der Charaktere in |
\d{1,2} | Zahlenwert von 1 bis 2 Stellen |
\Z | Das Ende der Zeichenfolge |
<?php
function pick_date(string $date) :array {
if (preg_match('/\A(\d{4})*[-\/]*(\d{1,2})[-\/]*(\d{1,2}) *((\d{1,2}):(\d{1,2})(:(\d{1,2}))*)*\Z/', $date, $matches)) {
return [
'Y' => isset($matches[1]) ?intval($matches[1]) : -1,
'm' => isset($matches[2]) ?intval($matches[2]) : -1,
'd' => isset($matches[3]) ?intval($matches[3]) : -1,
'H' => isset($matches[5]) ?intval($matches[5]) : -1,
'i' => isset($matches[6]) ?intval($matches[6]) : -1,
's' => isset($matches[8]) ?intval($matches[8]) : -1
];
} else {
return [];
}
}
print_r(pick_date('2017-07-03 13:15:03'));
print_r(pick_date('2017-07-3 13:01'));
print_r(pick_date('2017/07/03 13'));
print_r(pick_date('2017/07-3 13:1:3'));
print_r(pick_date('201773 13:00'));
Ausführungsergebnis
Array
(
[Y] => 2017
[m] => 7
[d] => 3
[H] => 13
[i] => 15
[s] => 3
)
Array
(
[Y] => 2017
[m] => 7
[d] => 3
[H] => 13
[i] => 1
[s] => -1
)
Array
(
)
Array
(
[Y] => 2017
[m] => 7
[d] => 3
[H] => 13
[i] => 1
[s] => 3
)
Array
(
[Y] => 2017
[m] => 7
[d] => 3
[H] => 13
[i] => 0
[s] => -1
)
Im Gegensatz zu PHP ist keine Abgrenzung erforderlich.
Wenn Ihnen die Bestellung nicht bekannt ist, können Sie auch "dict" anstelle von "OrderedDict" verwenden.
Sie können das gleiche Ausgabeergebnis wie PHP mit findall
erhalten.
import re
from collections import OrderedDict
def pick_date(date):
pattern = r'\A(\d{4})*[-\/]*(\d{1,2})[-\/]*(\d{1,2}) *((\d{1,2}):(\d{1,2})(:(\d{1,2}))*)*\Z'
match = re.findall(pattern, date)
try:
elements = match[0]
return OrderedDict((
('Y', elements[0]),
('m', elements[1]),
('d', elements[2]),
('H', elements[4]),
('i', elements[5]),
('s', elements[7])
))
except IndexError:
return OrderedDict()
print(pick_date('2017-07-03 13:15:03'))
print(pick_date('2017-07-3 13:01'))
print(pick_date('2017/07/03 13'))
print(pick_date('2017/07-3 13:1:3'))
print(pick_date('201773 13:00'))
Ausgabeergebnis
OrderedDict([('Y', '2017'), ('m', '07'), ('d', '03'), ('H', '13'), ('i', '15'), ('s', '03')])
OrderedDict([('Y', '2017'), ('m', '07'), ('d', '3'), ('H', '13'), ('i', '01'), ('s', '')])
OrderedDict()
OrderedDict([('Y', '2017'), ('m', '07'), ('d', '3'), ('H', '13'), ('i', '1'), ('s', '3')])
OrderedDict([('Y', '2017'), ('m', '7'), ('d', '3'), ('H', '13'), ('i', '00'), ('s', '')])
In diesem Fall ist die folgende Methode je nach Szenario möglicherweise besser, ohne reguläre Ausdrücke zu verwenden. Wird es hier sein, wenn es streng ist?
<?php
date_default_timezone_set('Asia/Tokyo');
function pick_date(string $date) : array {
$dt = new DateTime();
return [
'y' => $dt->setTimestamp(strtotime($date))->format('Y'),
'm' => $dt->format('m'),
'd' => $dt->format('d'),
'H' => $dt->format('H'),
'i' => $dt->format('i'),
's' => $dt->format('s'),
];
}
print_r(pick_date('2017-07-03 13:15:03'));
print_r(pick_date('2017-07-3 13:01'));
print_r(pick_date('2017/07/03 13'));
print_r(pick_date('2017/07-3 13:1:3'));
print_r(pick_date('201773 13:00'));
Ausgabeergebnis
Array
(
[y] => 2017
[m] => 07
[d] => 03
[H] => 13
[i] => 15
[s] => 03
)
Array
(
[y] => 2017
[m] => 07
[d] => 03
[H] => 13
[i] => 01
[s] => 00
)
Array
(
[y] => 1970
[m] => 01
[d] => 01
[H] => 09
[i] => 00
[s] => 00
)
Array
(
[y] => 1970
[m] => 01
[d] => 01
[H] => 09
[i] => 00
[s] => 00
)
Array
(
[y] => 1970
[m] => 01
[d] => 01
[H] => 09
[i] => 00
[s] => 00
)
Ich habe darüber nachgedacht, wie man einmal mit "strptime" von "datetime" konvertiert, aber im Gegensatz zu "strtotime" von PHP ist es notwendig, "format" anzugeben, damit ich etwas Ähnliches nicht tun kann.
Überprüfen Sie, ob es dem E-Mail-Format entspricht. Siehe hier als Referenz.
/\A^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$\Z/
Notation | Bedeutung |
---|---|
/ | Trennzeichen |
\A | Der Anfang der Zeichenfolge |
[1] | []Beginnt mit einem der Zeichen (Zeichensatz) in |
a-z | Zeichen von a bis z |
() | Als Set behandeln |
+ | Wiederholen Sie eines oder mehrere der vorherigen Muster |
\. | Punkt(".") Entkomme, um zu bestimmen |
* | Wiederholen Sie 0 oder mehr Mal des vorherigen Musters |
[a-z]{2,} | Zwei oder mehr Kleinbuchstaben |
\Z | Das Ende der Zeichenfolge |
<?php
function validate_email_format(string $email) : int {
return preg_match('/\A^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$\Z/', $email);
}
print(validate_email_format('[email protected]'). PHP_EOL);
print(validate_email_format('[email protected]'). PHP_EOL);
print(validate_email_format('[email protected]'). PHP_EOL);
print(validate_email_format('[email protected]'). PHP_EOL);
print(validate_email_format('test@testcom'). PHP_EOL);
Ausgabeergebnis
1
0
0
0
0
import re
def validate_email_format(email):
pattern = r'\A^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$\Z'
return 1 if re.match(pattern, email) else 0
print(validate_email_format('[email protected]'))
print(validate_email_format('[email protected]'))
print(validate_email_format('[email protected]'))
print(validate_email_format('[email protected]'))
print(validate_email_format('test@testcom'))
Ausgabeergebnis
1
0
0
0
0
Überprüfen Sie, ob es dem URL-Format entspricht (in diesem Fall berücksichtigen Sie auch "ftp"). Ich habe auf [hier] verwiesen (http://wepicks.net/phpsample-preg-url/).
/^(https?|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?([0-9]+)?\/?/i
Notation | Bedeutung |
---|---|
/ | Trennzeichen |
() | Ausdruckssatz, |
^() | Beginnt mit einer Reihe von Ausdrücken |
? | Mit oder ohne vorheriges Muster |
| | Bedeutung von OR |
[] | Zeichensatz,[]Einer der Charaktere in |
(?:) | Stellen Sie ein, dass nicht erfasst werden soll |
+ | Wiederholen Sie eines oder mehrere der vorherigen Muster |
* | Wiederholen Sie 0 oder mehr Mal des vorherigen Musters |
i | Groß- und Kleinschreibung wird nicht berücksichtigt |
<?php
function pick_url(string $url) : array {
if (preg_match('/^(https?|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?([0-9]+)?\/?/i', $url, $matches)) {
return [
$matches[0] ?? "",
$matches[1] ?? ""
];
} else {
return ["", ""];
}
}
print_r(pick_url('http://test.xxx?a=b'));
print_r(pick_url('https://test.xxx/a/b/'));
print_r(pick_url('ftp://test.xxx'));
print_r(pick_url('ftps://test.xxx'));
print_r(pick_url('https:///test.xxx'));
Ausgabeergebnis
Array
(
[0] => http://test.xxx
[1] => http
)
Array
(
[0] => https://test.xxx/
[1] => https
)
Array
(
[0] => ftp://test.xxx
[1] => ftp
)
Array
(
[0] =>
[1] =>
)
Array
(
[0] =>
[1] =>
)
import re
def pick_url(url):
pattern = r'^(https?|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?([0-9]+)?\/?'
match = re.compile(pattern, re.IGNORECASE).findall(url)
try:
elements = match[0]
return [elements[0], elements[1]]
except IndexError:
return ["", ""]
print(pick_url('http://test.xxx?a=b'))
print(pick_url('https://test.xxx/a/b/'))
print(pick_url('ftp://test.xxx'))
print(pick_url('ftps://test.xxx'))
print(pick_url('https:///test.xxx'))
Ausgabeergebnis
['http', 'test.xxx']
['https', 'test.xxx']
['ftp', 'test.xxx']
['', '']
['', '']
In diesem Beispiel ein Beispiel, das das Wort 'abc' durch 'ABC' ersetzt. Zu dieser Zeit hatte ich Schwierigkeiten mit der Methode, Wort für Wort neu zu schreiben, also machte ich mir eine Notiz. Tatsächlich ist dies auch nicht streng, deshalb ändere ich es von Fall zu Fall.
/(\b)(abc)(\b)/
Notation | Bedeutung |
---|---|
/ | Trennzeichen |
() | Ausdruckssatz |
\b | Entspricht den Zeichen, die an englische Wörter grenzen |
<?php
function replace_abc(string $s) : string {
return preg_replace('/(\b)(abc)(\b)/', '${1}ABC${3}', $s);
}
print(replace_abc('abcd abc" dabcd abc'). "\n");
print(replace_abc('abc dabc abc d "abc"'). "\n");
print(replace_abc('abcd +abc" abc abc?'). "\n");
print(replace_abc('a!abc \'abc\' sabcs abc\'s!'). "\n");
print(replace_abc('ababc? \'abc?\' sabcs abc!?'). "\n");
Ausgabeergebnis
abcd ABC" dabcd ABC
ABC dabc ABC d "ABC"
abcd +ABC" ABC ABC?
a!ABC 'ABC' sabcs ABC's!
ababc? 'ABC?' sabcs ABC!?
$ {N}
in '$ {1} ABC $ {3}'
bedeutet das n-te übereinstimmende Zeichen.Wie bei PHP ist keine Abgrenzung erforderlich. Außerdem wird die Methode zum Festlegen des Formats nach dem Ersetzen als "\ 1" anstelle von "$ {1}" beschrieben.
import re
def replace_abc(s):
return re.sub(r'(\b)(abc)(\b)', r'\1ABC\3', s)
print(replace_abc('abcd abc" dabcd abc'))
print(replace_abc('abc dabc abc d "abc"'))
print(replace_abc('abcd +abc" abc abc?'))
print(replace_abc('a!abc \'abc\' sabcs abc\'s!'))
print(replace_abc('ababc? \'abc?\' sabcs abc!?'))
Ausgabeergebnis
abcd ABC" dabcd ABC
ABC dabc ABC d "ABC"
abcd +ABC" ABC ABC?
a!ABC 'ABC' sabcs ABC's!
ababc? 'ABC?' sabcs ABC!?
Angenommen, Sie möchten eine CSV-Spalte erhalten, die doppelte Anführungszeichen wie die folgende enthält.
test.csv
a,b,c
"a,b","b,c","c,d"
"a,b,\"a,b\",,c","a,,b,,",c
"a,,","a,b,\"a,b,c\",c,d,","a\"a,b\",c"
Erwartetes Ergebnis (()Wird zur einfachen Identifizierung beschrieben)
(a), (b), (c)
(a,b), (b,c), (c,d)
(a,b,\"a,b\",,c), (a,,b,,), (c)
(a,,), (a,b,\"a,b,c\",c,d,), (a\"a,b\",c)
Es funktioniert nicht, wenn das doppelte Anführungszeichen ein doppeltes Anführungszeichen enthält. Es mag einen Weg geben, aber hier verwenden wir reguläre Ausdrücke. Ist es bei dieser Methode ein Bild, das mit "preg_split (" /, (?! ") /", $ Columns) extrahiert wird? Als ich mich mit diesen Dingen befasste, gab es viele Möglichkeiten, sie durch Programmierung zu extrahieren. Lassen Sie es uns mit einem regulären Ausdruck realisieren.
csv.php
<?php
$file = fopen("test.csv", "r");
if ($file) {
while (($columns = fgetcsv($file, 0, ',', '"', '"')) !== FALSE) {
print_r($columns);
}
}
fclose($file);
Ausgabeergebnis
Array
(
[0] => a
[1] => b
[2] => c
)
Array
(
[0] => "a
[1] => b","b
[2] => c","c
[3] => d"
)
Array
(
[0] => "a
[1] => b
[2] => \"a
[3] => b\"
[4] =>
[5] => c","a
[6] =>
[7] => b
[8] => ,"
[9] => c
)
Array
(
[0] => "a
[1] => ,","a
[2] => b
[3] => \"a
[4] => b
[5] => c\"
[6] => c
[7] => d,","a\"a
[8] => b\"
[9] => c"
)
Es scheint ziemlich genau zu sein. Das Beispiel test.csv
scheint etwas zu aggressiv, aber ich kann nichts sagen, weil ich tatsächlich auf eine ähnliche CSV gestoßen bin.
import csv
with open('test.csv') as f:
r = csv.reader(f)
for column in r:
print(column)
Ausgabeergebnis
['a', 'b', 'c']
['a,b', 'b,c', 'c,d']
['a,b,\\a', 'b\\"', '', 'c"', 'a,,b,,', 'c']
['a,,', 'a,b,\\a', 'b', 'c\\"', 'c', 'd', ',a\\"a', 'b\\"', 'c"']
/(?:\n|\r|\r\n)/
Notation | Bedeutung |
---|---|
/ | Trennzeichen |
() | Ausdruckssatz, |
(?:) | Stellen Sie ein, dass nicht erfasst werden soll |
| | Bedeutung von OR |
[] | Zeichensatz,[]Einer der Charaktere in |
+ | Wiederholen Sie eines oder mehrere der vorherigen Muster |
(?:)
Über,$str = preg_replace('/(?:\n|\r|\r\n)/', '', $str);
Es kann auch verwendet werden, wenn Zeilenvorschubcodes wie z<?php
function my_generator(string $name) : Iterator {
$from = function () use ($name) {
$file = fopen($name, "r");
if ($file) {
while ($line = fgets($file)) {
yield $line;
}
}
fclose($file);
};
yield from $from();
}
$pattern = '/\"(?:\\\"|[^\"])+\"/';
$bks = [];
foreach (my_generator("test.csv") as $v) {
// "Speichern Sie den darin enthaltenen Wert und ersetzen Sie ihn durch eine eindeutige ID
$columns = preg_replace_callback($pattern, function ($matches) use (&$bk) {
$index = uniqid();
$bk[$index] = $matches[0];
return $index;
}, $v);
//Zeilenvorschubcode entfernen
$columns = preg_split('/,/', preg_replace("/\r|\n/", "", $columns));
//Stellen Sie den durch id ersetzten Wert wieder her
$new_columns = array_map(function ($column) use ($bk) {
if (!empty($bk) && array_key_exists($column, $bk)) {
return $bk[$column];
} else {
return $column;
}
}, $columns);
print_r($new_columns);
}
Ausgabeergebnis
Array
(
[0] => a
[1] => b
[2] => c
)
Array
(
[0] => "a,b"
[1] => "b,c"
[2] => "c,d"
)
Array
(
[0] => "a,b,\"a,b\",,c"
[1] => "a,,b,,"
[2] => c
)
Array
(
[0] => "a,,"
[1] => "a,b,\"a,b,c\",c,d,"
[2] => "a\"a,b\",c"
)
import re
import uuid
bks = {}
def my_generator():
with open('test.csv') as lines:
yield from lines
def repl(m):
index = str(uuid.uuid4())
bks[index] = m.group(0)
return index
pattern = r'\"(?:\\\"|[^\"])+\"'
for k, v in enumerate(my_generator()):
columns = re.sub(pattern, repl, v).rstrip('\r\n').split(",")
new_columns = []
for c in columns:
if c in bks:
new_columns.append(bks[c])
else:
new_columns.append(c)
print(new_columns)
Ausgabeergebnis
['a', 'b', 'c']
['"a,b"', '"b,c"', '"c,d"']
['"a,b,\\"a,b\\",,c"', '"a,,b,,"', 'c']
['"a,,"', '"a,b,\\"a,b,c\\",c,d,"', '"a\\"a,b\\",c"']
Es scheint Fälle zu geben, in denen die doppelten Anführungszeichen in den doppelten Anführungszeichen nicht maskiert werden. Ich möchte einen Code ausprobieren, der Notationen wie "a, b", "c", "a, b," a "," b "", c "verarbeiten kann.
Recommended Posts