正则表达式替换为数组

时间:2018-03-11 09:32:20

标签: php regex preg-replace

我目前正在编写一个脚本来匹配来自不同供应商的IT设备模型,其想法是删除末尾的-XXX编号,结尾的P或名称中间的P- 示例模型是

DH-HAC-HDBW3802EP-Z     HAC-HDBW3802E-Z     
DH-HAC-HDBW3802EP-ZH    HAC-HDBW3802E-ZH        
DH-HAC-HDW1000MP-028    HAC-HDW1000M        
DH-HAC-HDW1000RP-028    HAC-HDW1000R        
DH-HAC-HDW1100EMP-02    HAC-HDW1100EM       
DH-HAC-HDW1100EMP-03    HAC-HDW1100EM       
DH-HAC-HDW1100MP        HAC-HDW1100M        
DH-HAC-HDW1100MP-036    HAC-HDW1100M        
DH-HAC-HDW1100RP-028    HAC-HDW1100R        
DH-HAC-HDW1100RP-VF     HAC-HDW1100R-VF

现在我正在使用一个相当复杂的代码,我必须承认,确实有效,但我内心深处有一点想要正则表达它*我知道,如果它有效,不要惹它* 清理名称结尾的功能看起来像

function beautifyDahua($text)
{
    $text = str_replace('DHI-', '', $text);
    $text = str_replace('DH-', '', $text);

    if (empty($text)) {
        return 'n-a';
    }

//if begins with IPC sau HAC, clean further

 elseif (substr( $text, 0, 4 ) === "IPC-" OR substr( $text, 0, 4 ) === "HAC-") {

    $text = str_replace('AP-028', 'A', $text);
    $text = str_replace('AP-036', 'A', $text);
    $text = str_replace('AP', 'A', $text);
    $text = str_replace('BP-028', 'B', $text);
    $text = str_replace('BP-036', 'B', $text);
    $text = str_replace('BP', 'B', $text);
    $text = str_replace('CP-', 'C-', $text);
    $text = str_replace('DP-036', 'D', $text);
    $text = str_replace('DP-', 'D-', $text);
    $text = str_replace('EMP-03', 'EM', $text);
    $text = str_replace('EMP-02', 'EM', $text);
    $text = str_replace('EMP-', 'EM-', $text);
    $text = str_replace('EP-036', 'E', $text);
    $text = str_replace('EP-028', 'E', $text);
    $text = str_replace('EP-03', 'E', $text);
    $text = str_replace('EP-02', 'E', $text);
    $text = str_replace('EP-', 'E-', $text);
    $text = str_replace('EP', 'E', $text);
    $text = str_replace('FP-03', 'F', $text);
    $text = str_replace('FP-02', 'F', $text);
    $text = str_replace('FP-', 'F-', $text);
    $text = str_replace('FP', 'F', $text);
    $text = str_replace('RMP-03', 'RM', $text);
    $text = str_replace('RMP-02', 'RM', $text);
    $text = str_replace('RMP-', 'RM', $text);
    $text = str_replace('RMP', 'RM', $text);
    $text = str_replace('RP-028', 'R', $text);
    $text = str_replace('RP-036', 'R', $text);
    $text = str_replace('RP-', 'R-', $text);
    $text = str_replace('RP', 'R', $text);
    $text = str_replace('SP-036', 'S', $text);
    $text = str_replace('SP-028', 'S', $text);
    $text = str_replace('SP-', 'S-', $text);
    $text = str_replace('SP', 'S', $text);
    $text = str_replace('SLP-03', 'SL', $text);
    $text = str_replace('TP-', 'T-', $text);
    $text = str_replace('MP-036', 'M', $text);
    $text = str_replace('MP-028', 'M', $text);
    $text = str_replace('MP', 'M', $text);
    return $text;
}
 else {

    return $text;
}
}

对于数字我有\b-0(\d|\d\d)\b这样的正则表达式 但是对于P情况,我在脑海中。

关于如何解决这个问题的任何建议?

4 个答案:

答案 0 :(得分:1)

您的正则表达式\b-0(\d|\d\d)\b可以写为-0\d{1,2}。对于这场比赛,我认为你不需要边界\b这个词。

试试这样:

(?:DHI?-)?(?:IPC|HAC)-HDB?W\d+[A-Z]+\K(?:P-0\d{1,2}|P)

正则表达式使用\K重置报告的匹配的起点并匹配之后的内容。 然后你可以用空字符串替换所选匹配。

<强>解释

  • (?:非捕获组
    • DHI?-将DH与可选的captital I匹配
  • )?关闭非捕获组
  • (?:非捕获组
    • IPC|HAC匹配IPC或HAC
  • )关闭非捕获组
  • -HDB?W匹配破折号HD,可选B和W
  • \d+匹配一个或多个数字
  • [A-Z]+匹配一个或多个大写字符
  • \K重置报告的匹配的起点
  • (?:非捕获组(这将包含您的匹配)
    • P-匹配P -
    • 0\d{1,2}匹配0和2位(或\d{2,3}匹配2或3位数字)
    • |
    • P匹配P
  • )关闭非捕获组

Demo php

答案 1 :(得分:0)

这里有一些东西,但不确定它是否适合你:

preg_replace("/\b(DH-)?(HAC-)(\w+\d+)(\w)(\w*)(-?\d+)?/", "$2$3$4", $input_lines);

所以基本上它匹配单词与可选的DH-后跟HAC-后跟任意数量的字母后跟任意数字的数字,后跟字母(至少2个可选地后跟-numbers

这里有一个hacky部分,因为结尾可选地匹配-\d+但是在替换中没有使用它会剥离它但它与-\w不匹配所以如果尾随人物存在,他们将被保留。但是,如果这是句子的一部分,这将失败。

答案 2 :(得分:0)

这是我建议你的正则表达式:

public class SmsBroadcastReceiver extends BroadcastReceiver {


private static final String TAG = "SmsBroadcastReceiver";

private Listener listener;

public SmsBroadcastReceiver() {

}


@SuppressLint("MissingPermission")
@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION)) {
        String smsSender = "";
        String smsBody = "";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
                smsSender = smsMessage.getDisplayOriginatingAddress();
                smsBody += smsMessage.getMessageBody();
            }
        } else {
            Bundle smsBundle = intent.getExtras();
            if (smsBundle != null) {
                Object[] pdus = (Object[]) smsBundle.get("pdus");
                if (pdus == null) {
                    // Display some error to the user
                    Log.e(TAG, "SmsBundle had no pdus key");
                    return;
                }
                SmsMessage[] messages = new SmsMessage[pdus.length];
                for (int i = 0; i < messages.length; i++) {
                    messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                    smsBody += messages[i].getMessageBody();
                }
                smsSender = messages[0].getOriginatingAddress();
            }
        }


        if (smsBody.startsWith("Lost")) {
            if (listener != null) {
                listener.onTextReceived(smsBody);
                Log.e(TAG, "SMS RECEIVED");
            }




            Toast.makeText(context, smsBody, Toast.LENGTH_SHORT).show();
            SmsManager.getDefault().sendTextMessage(smsSender, null, "Your Phone is at latitude,longitude ", null, null);

        }


    }

}

void setListener(Listener listener) {
    this.listener = listener;
}

interface Listener {
    void onTextReceived(String text);
}

 }

以及使用preg_replace functionPattern: (?:DHI?-)?((?:HAC|IPC)-[A-Z0-9]+)(?:P-\d+|P) Replacement: \1 实施:

PHP

您可以访问this link来查看有效的演示。

答案 3 :(得分:0)

在弄乱@apokryfos解决方案后,我来到了

$text = preg_replace("/\b(DHI-|DH-)?(HAC-|IPC-)(\w+\d+)(\w(M|L)?)(P)(\w*)(-?\d+)?/", "$2$3$4", $text);
$text = preg_replace("/\b(DHI-|DH-)?/", "", $text);

但是我看到Thomassos解决方案开箱即用,我将不得不检查我所拥有的1200多个示例,并且看看哪一个在我的情况下效果最好,无论如何,谢谢你的支持。