![](/img/trans.png)
[英](Problems with java.util.regex.Pattern) checking string for digits and letters
[英]Java regex for identifiers (letters, digits and underscores)
假設您給出了一個看起來像這樣的輸入(identifier1 identifier_2 23 4)
。
我想在每個標識符之后添加一個#
符號,它可以包含字母、數字和下划線。 它們只能以字母開頭,后跟字母、數字和下划線的變體。 我的方法是這樣的:
input.replaceAll("[A-Za-z0-9_]+", "$0#");
但是,這也會在我想排除的每個數字后面加上#
符號。 結果應該是(identifier1# identifier_2# 23 4)
。 是否有可能用正則表達式解決這個問題?
增量Java說:
- 每個標識符必須至少包含一個字符。
- 必須從以下字符中選擇第一個字符:字母,下划線或美元符號。 第一個字符不能為數字。
- 其余字符(第一個字符除外)可以來自:字母,數字,下划線或美元符號。 換句話說,它可以是任何有效的標識符字符。
簡而言之,標識符是從字母,數字,下划線或美元符號中選擇的一個或多個字符。 唯一的限制是第一個字符不能為數字。
所以,你最好用
String pattern = "(?:\\b[_a-zA-Z]|\\B\\$)[_$a-zA-Z0-9]*+";
累積 使用正則表達式表示標識符時 ,標識符regex為[_a-zA-Z][_a-zA-Z0-9]*
。
因此,您可以使用
String pattern = "\\b[_a-zA-Z][_a-zA-Z0-9]*\\b";
注意 ,它允許_______
。
您可以使用
String p = "\\b_*[a-zA-Z][_a-zA-Z0-9]*\\b";
為了避免這種情況。 請參閱IDEONE演示 。
String s = "(identifier1 identifier_2 23 4) ____ 33";
String p = "\\b_*[a-zA-Z][_a-zA-Z0-9]*\\b";
System.out.println(s.replaceAll(p, "$0#"));
輸出: (identifier1# identifier_2# 23 4) ____ 33
您可以使用以下模式:
String p = "\\b(?!\\d+\\b)[A-Za-z0-9]+(?:_[A-Za-z0-9]+)*\\b";
或(如果_
可以出現在末尾):
String p = "\\b(?!\\d+\\b)[A-Za-z0-9]+(?:_[A-Za-z0-9]*)*\\b";
該模式要求整個單詞(因為表達式用單詞邊界\\b
包圍)不應等於數字(使用(?!\\d+\\b)
),並且展開的部分[A-Za-z0-9]+(?:_[A-Za-z0-9])*
匹配非下划線單詞字符塊,后跟零個或多個下划線序列,再后跟非下划線單詞字符塊。
IDEONE演示 :
String s = "(identifier1 identifier_2 23 4) ____ 33";
String p = "\\b(?!\\d+\\b)[A-Za-z0-9]+(?:_[A-Za-z0-9]*)*\\b";
System.out.println(s.replaceAll(p, "$0#"));
輸出: (identifier1# identifier_2# 23 4) ____ 33
您當前的正則表達式說
一個或多個大寫或小寫字母,數字或下划線,順序不限。
根據該正則表達式, 54
是有效標識符。
你真的想寫
字母,后跟任意數量的字母,數字或下划線,順序不限
可以用以下代碼編寫:
input.replaceAll("[A-Za-z][A-Za-z0-9_]*", "$0#");
Wiktor指出,此正則表達式仍將匹配非標識符形式的內容中的“標識符”。 要解決此問題,您可以使用以下變體:
input.replaceAll("\\b([A-Za-z][A-Za-z0-9_]*)\\b", "$1#")
此拒絕123ab123
作為有效的標識符,但接受ab123
在123 ab123
如果您想使用 java 來讀取 java,java 可以為您提供: "\\b\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*\\b"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.