我将用PHP演示我的例子。我正在测试引用的字符串是否正确关闭(例如,如果以dq开头,引用的字符串必须以双引号关闭)。引号之间必须至少有1个字符,并且引号之间的字符集不能包含相同的开始/结束引号字符。例如:
$myString = "hello";// 'hello' also good but "hello' should fail
if (preg_match("/^(\")?[^\"]+(?(1)\")|(\')?[^\']+(?(1)\')$/", $myString)) {
die('1');
} else {
die('2');
}
// The string '1' is outputted which is correct
我是条件正则表达式的新手,但对我来说,似乎我不能使preg_match()更简单。这是对的吗?
答案 0 :(得分:2)
要做到这一点,不需要使用“条件功能”。但是你需要检查字符串从开始到结束(换句话说,你不能只检查字符串的一部分):
E/AndroidRuntime: FATAL EXCEPTION: GLThread 19364
Process: com.davidheadrick.mariogame, PID: 12739
com.badlogic.gdx.utils.GdxRuntimeException: com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load dependencies of asset: mario_music.ogg
at com.badlogic.gdx.assets.AssetManager.handleTaskError(AssetManager.java:570)
at com.badlogic.gdx.assets.AssetManager.update(AssetManager.java:375)
at com.badlogic.gdx.assets.AssetManager.finishLoading(AssetManager.java:396)
at com.davidheadrick.mariogame.MarioGame.create(MarioGame.java:38)
at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:275)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1550)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1278)
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load dependencies of asset: mario_music.ogg
at com.badlogic.gdx.assets.AssetLoadingTask.handleAsyncLoader(AssetLoadingTask.java:121)
at com.badlogic.gdx.assets.AssetLoadingTask.update(AssetLoadingTask.java:90)
at com.badlogic.gdx.assets.AssetManager.updateTask(AssetManager.java:498)
at com.badlogic.gdx.assets.AssetManager.update(AssetManager.java:373)
at com.badlogic.gdx.assets.AssetManager.finishLoading(AssetManager.java:396)
at com.davidheadrick.mariogame.MarioGame.create(MarioGame.java:38)
at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:275)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1550)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1278)
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: com.badlogic.gdx.utils.GdxRuntimeException: Error loading audio file: mario_music.ogg
Note: Internal audio files must be placed in the assets directory.
at com.badlogic.gdx.utils.async.AsyncResult.get(AsyncResult.java:46)
at com.badlogic.gdx.assets.AssetLoadingTask.handleAsyncLoader(AssetLoadingTask.java:119)
... 8 more
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Error loading audio file: mario_music.ogg
Note: Internal audio files must be placed in the assets directory.
at com.badlogic.gdx.backends.android.AndroidAudio.newMusic(AndroidAudio.java:120)
at com.badlogic.gdx.assets.loaders.MusicLoader.loadAsync(MusicLoader.java:48)
at com.badlogic.gdx.assets.loaders.MusicLoader.loadAsync(MusicLoader.java:29)
at com.badlogic.gdx.assets.AssetLoadingTask.call(AssetLoadingTask.java:70)
at com.badlogic.gdx.assets.AssetLoadingTask.call(AssetLoadingTask.java:34)
at com.badlogic.gdx.utils.async.AsyncExecutor$2.call(AsyncExecutor.java:58)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed
at android.content.res.AssetManager.openAssetFd(Native Method)
at android.content.res.AssetManager.openFd(AssetManager.java:346)
at com.badlogic.gdx.backends.android.AndroidFileHandle.getAssetFileDescriptor(AndroidFileHandle.java:237)
at com.badlogic.gdx.backends.android.AndroidAudio.newMusic(AndroidAudio.java:110)
at com.badlogic.gdx.assets.loaders.MusicLoader.loadAsync(MusicLoader.java:48)
at com.badlogic.gdx.assets.loaders.MusicLoader.loadAsync(MusicLoader.java:29)
at com.badlogic.gdx.assets.AssetLoadingTask.call(AssetLoadingTask.java:70)
at com.badlogic.gdx.assets.AssetLoadingTask.call(AssetLoadingTask.java:34)
at com.badlogic.gdx.utils.async.AsyncExecutor$2.call(AsyncExecutor.java:58)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
如果您绝对希望引号内至少包含一个字符,则需要添加这些前瞻preg_match('~\A[^"\']*+(?:"[^"\\\\]*+(?:\\\\.[^"\\\\]*)*+"[^"\']*|\'[^\'\\\\]*+(?:\\\\.[^\'\\\\]*)*+\'[^"\']*)*+\z~s', $str)
和(?=[^"])
:
(?=[^'])
细节:
preg_match('~\A[^"\']*+(?:"(?=[^"])[^"\\\\]*+(?:\\\\.[^"\\\\]*)*+"[^"\']*|\'(?=[^\'])[^\'\\\\]*+(?:\\\\.[^\'\\\\]*)*+\'[^"\']*)*+\z~s', $str)
请注意,这些模式旨在处理转义字符。
大多数情况下,条件可以用简单的替换来替换。
顺便说一句:不要相信较短的图案总是比较长的图案更好,这是一个错误的想法。
答案 1 :(得分:1)
基于下面的两个观察,我构建了我的正则表达式,简单快速,但不处理转义引号
$str = "hello, I
said: \"How are you?\""
是否无效且未回复我也不是很难阅读的代码粉丝,因此我使用<<<
Nowdoc notation来避免以正则表达式模式转义任何内容
我的解决方案:
$strings = [
"'hello's the word'",
"'hello is the word'",
'"hello "there" he said"',
'"hello there he said"',
'"Hi',
"'hello",
"no quotes",
"''"
];
$regexp = <<< 'TEXT'
/^('|")(?:(?!\1).)+\1$/
TEXT;
foreach ($strings as $string):
echo "$string - ".(preg_match($regexp,$string)?'true':'false')."<br/>";
endforeach;
输出:
'hello's the word' - false
'hello is the word' - true
"hello "there" he said" - false
"hello there he said" - true
"Hi - false
'hello - false
no quotes - false
'' - false
工作原理:
^('|") //starts with single or double-quote
(?: //non-capturing group
(?!\1) //next char is not the same as first single/double quote
. //advance one character
)+ //repeat group with next char (there must be at least one char)
\1$ //End with the same single or double-quote that started the string