Php 正则表达式删除除数字和一个字符以外的所有内容

Php 正则表达式删除除数字和一个字符以外的所有内容,php,regex,Php,Regex,我需要删除除数字以外的所有内容,如果字符串中存在一个字符,则删除其中的一个。这是一个街道名称,我需要提取它的门牌号。字符串后面可能还有一些内容,但不一定 原始字符串类似于 Wagnerstrasse 3a platz53,eingang 3,Zi.3005 我用如下数字提取街道: preg_match('/^([^\d]*[^\d\s]) *(\d.*)$/', $address, $match); 然后,我对“Wagnerstrasse 3a”做了一个if语句 我需要更改正则表达式以获得

我需要删除除数字以外的所有内容,如果字符串中存在一个字符,则删除其中的一个。这是一个街道名称,我需要提取它的门牌号。字符串后面可能还有一些内容,但不一定

原始字符串类似于

Wagnerstrasse 3a platz53,eingang 3,Zi.3005 
我用如下数字提取街道:

preg_match('/^([^\d]*[^\d\s]) *(\d.*)$/', $address, $match);
然后,我对“Wagnerstrasse 3a”做了一个if语句

我需要更改正则表达式以获得以下一个字母,即使中间有空格,但仅当它是一个字母时,以便我的if在此条件下为true/更好的正则表达式只删除以下内容以外的所有内容:

Wagnerstrasse 3a       <-- expected result: 3a
Wagnerstrasse 3 a      <--- expected result 3 a 
Wagnerstrasse 3        <--- expected result 3
Wagnerstrasse 3 a bac  <--- expected result 3 a

Wagnerstrasse3a您可以尝试使用单词边界的类似方法:

preg_match('~\b\d+(?: ?[a-z])?\b~', $txt, $m)
字母位于可选组中,前面有可选空格。即使没有字母,最后一个单词的边界也将与数字和后面的内容(空格、逗号、字符串结尾…)匹配

注意:为了避免街道名称中出现数字,您可以尝试将模式锚定在前瞻中的第一个逗号处,例如:

preg_match('~\b\d+(?: ?[a-z])?\b(?= [^\s]*,)~', $txt, $m)

我让您用您的案例改进此子模式。

您可以尝试使用单词边界的类似方法:

preg_match('~\b\d+(?: ?[a-z])?\b~', $txt, $m)
<?php
$s1 = 'Wagnerstrasse 3 platz53,eingang 3,Zi.3005';
$s2 = 'Wagnerstrasse 3a platz53,eingang 3,Zi.3005';
$s3 = 'Wagnerstrasse 3A platz53,eingang 3,Zi.3005';
$s4 = 'Wagnerstrasse 3 a platz53,eingang 3,Zi.3005';
$s5 = 'Wagnerstrasse 3 A platz53,eingang 3,Zi.3005';

//test all $s
preg_match('#^(.+? [0-9]* *[A-z]?)[^A-z]#', $s1, $m);

//if you want only the street number
//preg_match('#^.+? ([0-9]* *[A-z]?)[^A-z]#', $s1, $m);

echo $m[1];
?>
字母位于可选组中,前面有可选空格。即使没有字母,最后一个单词的边界也将与数字和后面的内容(空格、逗号、字符串结尾…)匹配

注意:为了避免街道名称中出现数字,您可以尝试将模式锚定在前瞻中的第一个逗号处,例如:

preg_match('~\b\d+(?: ?[a-z])?\b(?= [^\s]*,)~', $txt, $m)
我允许您通过案例改进此子模式。


<?php
$s1 = 'Wagnerstrasse 3 platz53,eingang 3,Zi.3005';
$s2 = 'Wagnerstrasse 3a platz53,eingang 3,Zi.3005';
$s3 = 'Wagnerstrasse 3A platz53,eingang 3,Zi.3005';
$s4 = 'Wagnerstrasse 3 a platz53,eingang 3,Zi.3005';
$s5 = 'Wagnerstrasse 3 A platz53,eingang 3,Zi.3005';

//test all $s
preg_match('#^(.+? [0-9]* *[A-z]?)[^A-z]#', $s1, $m);

//if you want only the street number
//preg_match('#^.+? ([0-9]* *[A-z]?)[^A-z]#', $s1, $m);

echo $m[1];
?>

在对该主题进行了更多的研究和数小时的地址检查(这么多地址)之后,我找到了一个解决方案,到目前为止,该解决方案没有失败。可能是我没有意识到,但它似乎很好。这是一个以前从未见过的正则表达式。。。如果行中没有数字,正则表达式将失败。所以我做了一些黑客攻击(提到数以百万计的9…)

基本上,ReGEX在结尾处查找数字是很好的,在文本的中间保留数字,但是对于上面提到的事实,如果街道以数字开头,则失败。所以我又做了一个小小的改动,把第一个数字放在后面,然后把它当作数字来抓

if ($this->startsWithNumber($data))
{
    $tmp = explode(' ', $data);
    $data = trim(str_replace($tmp[0], '', $data)) . ' ' . $tmp[0];
}
if (!preg_match('/[0-9]/',$data)) 
{
    $data .= ' 99999999999999999999999999999999999999999999999999999999999999999999999';
}
$data = preg_replace("/[^ \w]+/",'',$data);

                    $pcre = '/\A\s*
(.*?) # street
\s*
\x2f? # slash
(
    \pN+\s*[a-zA-Z]? # number + letter
    (?:\s*[-\x2f\pP]\s*\pN+\s*[a-zA-Z]?)* # cut
) # number
\s*\z/ux';
                    preg_match($regex, $data, $h);

$compare = strpos($h[2],'999999999999999999999999999999999999999999999999999999999999999999999999');
                    if ($compare !== false) {
                        $h[2] = null;
                    }
                    $this->receiverStreet[] = (isset($h[1])) ? $h[1] : null;
                    $this->receiverHouseNo[] = (isset($h[2])) ? $h[2]  : null;


在做了更多的研究和数小时的地址检查(这么多地址)之后,我找到了一个解决方案,直到现在,它还没有失败。可能是我没有意识到,但它似乎很好。这是一个以前从未见过的正则表达式。。。如果行中没有数字,正则表达式将失败。所以我做了一些黑客攻击(提到数以百万计的9…)

基本上,ReGEX在结尾处查找数字是很好的,在文本的中间保留数字,但是对于上面提到的事实,如果街道以数字开头,则失败。所以我又做了一个小小的改动,把第一个数字放在后面,然后把它当作数字来抓

if ($this->startsWithNumber($data))
{
    $tmp = explode(' ', $data);
    $data = trim(str_replace($tmp[0], '', $data)) . ' ' . $tmp[0];
}
if (!preg_match('/[0-9]/',$data)) 
{
    $data .= ' 99999999999999999999999999999999999999999999999999999999999999999999999';
}
$data = preg_replace("/[^ \w]+/",'',$data);

                    $pcre = '/\A\s*
(.*?) # street
\s*
\x2f? # slash
(
    \pN+\s*[a-zA-Z]? # number + letter
    (?:\s*[-\x2f\pP]\s*\pN+\s*[a-zA-Z]?)* # cut
) # number
\s*\z/ux';
                    preg_match($regex, $data, $h);

$compare = strpos($h[2],'999999999999999999999999999999999999999999999999999999999999999999999999');
                    if ($compare !== false) {
                        $h[2] = null;
                    }
                    $this->receiverStreet[] = (isset($h[1])) ? $h[1] : null;
                    $this->receiverHouseNo[] = (isset($h[2])) ? $h[2]  : null;


街道号码总是字符串中的第一个号码吗?(
Wagnerstrasse
听起来像是德国的一条街道:)它在德国:)在这种情况下,是的,街道编号将始终是字符串中的第一个数字。如果街道名称中有数字,那街道呢。例如,StraßE des 17。如果这会导致一个错误,我需要解析一个完全无序的列表,允许客户以任何方式输入他们的地址。真的,不管怎样,在三个不同的专栏里。。。所以这只是为了尽可能接近@user3584460我的正则表达式很烂,但这里有一个似乎有效的方法:街道号总是字符串中的第一个数字吗?(
Wagnerstrasse
听起来像是德国的一条街道:)它在德国:)在这种情况下,是的,街道编号将始终是字符串中的第一个数字。如果街道名称中有数字,那街道呢。例如,StraßE des 17。如果这会导致一个错误,我需要解析一个完全无序的列表,允许客户以任何方式输入他们的地址。真的,不管怎样,在三个不同的专栏里。。。所以这只是为了尽可能接近@USER3584460我在正则表达式方面很差劲,但这里有一些似乎有效的东西:谢谢你,这太完美了@迈克尔:谢谢,但正如我所说,第二种模式需要改进,这只是一个想法。谢谢,这太完美了@迈克尔:谢谢,但正如我所说,第二种模式需要改进,这只是一个想法。