正则表达式使用语言代码解析多语言字符串

bra*_*pus 0 php regex

我有多语言字符串格式如下:

[en]这是英语[es] estoesespañol[fr]C'estfrançaise[it]Questoèitaliano

语言的顺序并不总是相同,并不是所有语言都可用.

我正在尝试提取特定的语言字符串,但没有成功.语言字符串包含HTML,以及任何类型的特殊字符,空格,换行符,制表符等.

假设我想提取英语部分; 我需要一个正则表达式能够匹配[en]部分之后的所有内容(新行,回车符,特殊字符,制表符等),直到新语言字符串的开头:([az] {2})

这不起作用:还返回法语字符串,如果西班牙语字符串位于过去位置,则不返回任何内容.

/\[es\]((.|\n|\t|\r)*)(\[([a-z]{2})\])/u
Run Code Online (Sandbox Code Playgroud)

我不能写一个正则表达式:"[es]之后的任何东西,不是括号内的两个字母或字符串的结尾"

任何帮助都感激不尽!

Fra*_*Man 5

你真正的问题是贪婪匹配.有几种方法可以解决这个问题.懒惰匹配:

/\[es\]((?:.|\n|\t|\r)*?)\[([a-z]{2})\]/u
Run Code Online (Sandbox Code Playgroud)

负面的前瞻:

/\[es\]((?:(?!\[([a-z]{2})\])(?:.|\n|\t|\r))*)/u
Run Code Online (Sandbox Code Playgroud)

你看,Regex引擎是贪婪的,这意味着它捕获尽可能多的令牌并回溯直到它有一个匹配的字符串 - 常见的说法是引擎返回可能的最大捕获.您可以使用一个懒惰的匹配(任何匹配后跟一个?-所以??,*?,+?,等),其反转匹配模式和捕捉尽可能少,慢慢地抓住更多,直到它有一个匹配.您还可以使用前瞻来确保您匹配的通配符不包含分隔符字符串.

您还可以使用s修改器强制执行.匹配所有内容,包括换行符(它已匹配\t字符.

/\[es\](.*?)\[([a-z]{2})\]/su
Run Code Online (Sandbox Code Playgroud)

对这个故事要谨慎,如果赫拉克勒斯打架,你就会失败!如果你的字符串中有任何看起来像语言代码的东西,但不是 - 这个正则表达式会失败.

点击这里查看匹配.