ฉันมีสตริงที่มีสองคำพูดเดียวในนั้น'
ตัวละคร ในระหว่างเครื่องหมายคำพูดเดี่ยวคือข้อมูลที่ฉันต้องการ
ฉันจะเขียน regex เพื่อแยก "ข้อมูลที่ฉันต้องการ" จากข้อความต่อไปนี้ได้อย่างไร
mydata = "some string with 'the data i want' inside";
ฉันมีสตริงที่มีสองคำพูดเดียวในนั้น'
ตัวละคร ในระหว่างเครื่องหมายคำพูดเดี่ยวคือข้อมูลที่ฉันต้องการ
ฉันจะเขียน regex เพื่อแยก "ข้อมูลที่ฉันต้องการ" จากข้อความต่อไปนี้ได้อย่างไร
mydata = "some string with 'the data i want' inside";
คำตอบ:
สมมติว่าคุณต้องการส่วนระหว่างคำพูดเดียวใช้นิพจน์ปกตินี้ด้วยMatcher
:
"'(.*?)'"
ตัวอย่าง:
String mydata = "some string with 'the data i want' inside";
Pattern pattern = Pattern.compile("'(.*?)'");
Matcher matcher = pattern.matcher(mydata);
if (matcher.find())
{
System.out.println(matcher.group(1));
}
ผลลัพธ์:
ข้อมูลที่ฉันต้องการ
this 'is' my 'data' with quotes
มันจะหยุด แต่เนิ่น ๆ และกลับมาis
แทนที่จะจับคู่ตัวละครให้ได้มากที่สุดและกลับมาis' my 'data
ซึ่งเป็นพฤติกรรมเริ่มต้น
คุณไม่ต้องการ regex สำหรับสิ่งนี้
เพิ่ม apache คอมมอนส์ lang ลงในโครงการของคุณ ( http://commons.apache.org/proper/commons-lang/ ) จากนั้นใช้:
String dataYouWant = StringUtils.substringBetween(mydata, "'");
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
Pattern pattern = Pattern.compile(".*'([^']*)'.*");
String mydata = "some string with 'the data i want' inside";
Matcher matcher = pattern.matcher(mydata);
if(matcher.matches()) {
System.out.println(matcher.group(1));
}
}
}
มีหนึ่งซับง่าย ๆ สำหรับสิ่งนี้:
String target = myData.replaceAll("[^']*(?:'(.*?)')?.*", "$1");
ด้วยการทำให้กลุ่มการจับคู่เป็นตัวเลือกสิ่งนี้จะช่วยให้ไม่สามารถหาคำพูดได้โดยส่งคืนค่าว่างในกรณีนั้น
เนื่องจากคุณได้เลือกให้ Scala โซลูชันที่ไม่มี regex ซึ่งสามารถจัดการกับสตริงที่ยกมาหลาย ๆ ตัวได้อย่างง่ายดาย:
val text = "some string with 'the data i want' inside 'and even more data'"
text.split("'").zipWithIndex.filter(_._2 % 2 != 0).map(_._1)
res: Array[java.lang.String] = Array(the data i want, and even more data)
.split('\'').get(2)
บางสิ่งใน Java? ฉันคิดว่าคุณอาจจำเป็นต้องได้รับการสแกนสมองหากคุณคิดว่านั่นเป็นวิธีแก้ปัญหาที่อ่านได้ - ดูเหมือนว่ามีคนพยายามทำกอล์ฟรหัสให้ฉัน
String dataIWant = mydata.replaceFirst(".*'(.*?)'.*", "$1");
เช่นเดียวกับในจาวาสคริปต์:
mydata.match(/'([^']+)'/)[1]
regexp ที่แท้จริงคือ: /'([^']+)'/
หากคุณใช้ตัวแก้ไขที่ไม่ใช่โลภ (ตามโพสต์อื่น) มันเป็นเช่นนี้:
mydata.match(/'(.*?)'/)[1]
มันสะอาดกว่า
ในสกาลา
val ticks = "'([^']*)'".r
ticks findFirstIn mydata match {
case Some(ticks(inside)) => println(inside)
case _ => println("nothing")
}
for (ticks(inside) <- ticks findAllIn mydata) println(inside) // multiple matches
val Some(ticks(inside)) = ticks findFirstIn mydata // may throw exception
val ticks = ".*'([^']*)'.*".r
val ticks(inside) = mydata // safe, shorter, only gets the first set of ticks
String dataIWant = mydata.split("'")[1];
ดูการสาธิตสด
Apache Commons Lang มีโฮสต์ของตัวช่วยอรรถประโยชน์สำหรับ java.lang API ซึ่งเป็นวิธีการจัดการสตริงที่สะดุดตาที่สุด ในกรณีของคุณสตริงย่อยเริ่มต้นและสิ้นสุดเหมือนกันดังนั้นเพียงเรียกใช้ฟังก์ชันต่อไปนี้
StringUtils.substringBetween(String str, String tag)
Gets String ที่ซ้อนกันในระหว่างสองกรณีของสายเดียวกัน
หากสตริงย่อยเริ่มต้นและสิ้นสุดแตกต่างกันให้ใช้วิธีโอเวอร์โหลดต่อไปนี้
StringUtils.substringBetween(String str, String open, String close)
รับค่าสตริงที่ซ้อนระหว่างสองสตริง
หากคุณต้องการอินสแตนซ์ทั้งหมดของสตริงย่อยที่ตรงกันให้ใช้
StringUtils.substringsBetween(String str, String open, String close)
ค้นหาสตริงสำหรับสตริงคั่นด้วยเริ่มต้นและสิ้นสุดแท็ก กลับสตริงที่ตรงกันทั้งหมดในอาร์เรย์
สำหรับตัวอย่างที่เป็นปัญหาจะได้รับอินสแตนซ์ทั้งหมดของสตริงย่อยที่ตรงกัน
String[] results = StringUtils.substringsBetween(mydata, "'", "'");
คุณสามารถใช้สิ่งนี้ฉันใช้ในขณะที่วงเพื่อเก็บซับสตริงการแข่งขันทั้งหมดในอาร์เรย์ถ้าคุณใช้
if (matcher.find())
{
System.out.println(matcher.group(1));
}
คุณจะได้ซับสตริงการจับคู่เพื่อให้คุณสามารถใช้สิ่งนี้เพื่อรับซับสตริงการแข่งขันทั้งหมด
Matcher m = Pattern.compile("[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+").matcher(text);
// Matcher mat = pattern.matcher(text);
ArrayList<String>matchesEmail = new ArrayList<>();
while (m.find()){
String s = m.group();
if(!matchesEmail.contains(s))
matchesEmail.add(s);
}
Log.d(TAG, "emails: "+matchesEmail);
เพิ่มapache.commonsพึ่งพาpom.xmlของคุณ
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
และรหัสด้านล่างทำงาน
StringUtils.substringBetween(String mydata, String "'", String "'")
บางวิธีที่กลุ่ม (1) ไม่ได้ผลสำหรับฉัน ฉันใช้กลุ่ม (0) เพื่อค้นหารุ่น url
Pattern urlVersionPattern = Pattern.compile("\\/v[0-9][a-z]{0,1}\\/");
Matcher m = urlVersionPattern.matcher(url);
if (m.find()) {
return StringUtils.substringBetween(m.group(0), "/", "/");
}
return "v0";